JS – Object literal converted to number? [duplicate] - javascript

This question already has an answer here:
Why is {}+[] different from ({}+[])? [duplicate]
(1 answer)
Closed 6 years ago.
While playing around in Chrome's dev console, I noticed something that I don't understand:
({})+"" evaluates to "[object Object]", as I expected
{}+"" evaluates to 0 (number)
Replacing {} with {foo:"bar"} in either expression doesn't change the result, so it does seem to be being parsed as an object literal. Replacing "" with "42" yields 42, and replacing it with "foo" yields NaN.
What's going on here?

The context of the grammar changes.
({}) is an object literal expression evaluating to a new object so the code is effectively anObject+"". The parenthesis are defining here as they cause the code to be parsed as "(..some expression..)".
{}+"" is parsed as {};+"" since the {} are parsed as an empty block (as opposed to an object literal). This makes the code equivalent to +"" which yields 0.
{foo:"bar"} is parsed as block, with a label ("foo") to the singular expression "bar". There is no object literal.
Some (useful) ways where {..} will be parsed as an object literal expression:
z = {..}
({..})
f({..})
return {..}

Related

Why does object destructuring assignment throw an error when using template strings? [duplicate]

This question already has answers here:
Template String As Object Property Name
(3 answers)
Closed 4 years ago.
In JavaScript, it is possible to assign variables through object deconstruction like so:
let a = {b: 2};
let {b} = a;
console.log(b); // 2
Sometimes the property that needs to be accessed isn't a valid variable name, in which case an alternative identifier can be passed:
let a = {'words with spaces': 2};
let {'words with spaces': words_without_spaces} = a;
console.log(words_without_spaces); // 2
This works for both single quote strings and double quote strings. However, an error is thrown when trying to do the exact same thing with a template string:
let a = {'words with spaces': 2};
let {`words with spaces`: words_without_spaces} = a;
^^^^^^^^^^^^^^^^^^^
SyntaxError: Unexpected template string
Why does using a template string here cause an error whereas other strings don't? I understand that the template string could be defined as a variable beforehand and then passed using computed property brackets, but I'm just curious as to what the reason is behind the above code not working.
The language syntax allows for a property name in an object initializer or a descructuring left-hand-side of an assignment to be a string literal but not a template. That's just the way the grammar is defined.

Why property accessor does not work for an object literal [duplicate]

This question already has answers here:
What difference does it makes to parse something as an object literal rather than as a block?
(2 answers)
Why doesn't `{}.toString.apply(array)` work?
(1 answer)
Closed 5 years ago.
When I create an object, assign it to a variable, then everything works:
var obj = {"a": 1};
obj.a; // 1
But when I remove the variable, it does not work anymore:
{"a": 1}.a // Uncaught SyntaxError: Unexpected token :
And if I enclose the object literal in parentheses, it works again:
({"a": 1}).a // 1
I think the difference is that the object literal gets interpreted as a block, and the interpreter tries to execute the "a": 1 part, which is obviously wrong. Adding parentheses forces the object creation.
Am I on the right track? What are the rules whether something is considered a block vs an object?

why is 1[1] evaluated to undefined in javascript? [duplicate]

This question already has answers here:
Why is 0[0] syntactically valid?
(7 answers)
Closed 6 years ago.
Is the number 1 cast to an empty array implicitly?
> a = 1[1]
undefined
> console.log(a)
undefined
undefined
Is the number 1 cast to an empty array implicitly?
No. The number value is implicitly (and temporarily) converted to a number object and the property 1 is accessed on that object.
The bracket notation you are using ([1]) is not specific to arrays, every object property can be accessed via bracket notation. I.e. the following two are equivalent: obj.foo (dot notation) and obj['foo'] (bracket notation).
Number objects however don't have a property 1 and accessing a non-existing property returns undefined:
var numObj = new Number(1);
console.log(numObj[1]);
The implicit conversion happens every time you access a property on a primitive value, whether the property exists or not. In the following example, the primitive number value is also implicitly converted to an object and then its toFixed method is executed:
var num = 42;
console.log(num.toFixed(2));
// or equivalently to your example:
console.log(42['toFixed'](2))
Numbers, Strings, Booleans and Symbols have object equivalents. Null and Undefined don't.

JavaScript array and object in single variable? [duplicate]

This question already has answers here:
Add a property to a JavaScript array
(5 answers)
Closed 7 years ago.
I recently came across some code which I am a little confused about. Below is similar code, have a look:
var x = [];
console.log(x); // prints [] (no surprise)
x[0] = "abc";
console.log(x); // prints ["abc"] (no surprise)
x["test"] = "testing"
console.log(x); // prints ["abc"]
console.log(x.test); // prints "testing"
so in this case.. the same variable, x, is both array and an object. How is this possible? If it acts as both, then console.log(x) should print something like ["abc",test:"testing"] but that syntax is wrong.
So whats happening in this case?
All Arrays are Objects, (not only them, everything in JavaScript is an Object (except the primitives though))
console.log([] instanceof Object);
// true
just that they are special kind of objects which process integer keys differently.
So, you can expect them to act like normal JavaScript Objects. You can add arbitrary properties to them.
About the console.log result,
[ 'abc', test: 'testing' ]
is just a representation given by the implementation. If the representation has a key : value format, then it is a normal property associated with that array. That's all.

In JavaScript, if “Strings are objects” then why not Numbers too? [duplicate]

This question already has answers here:
Why can't I access a property of an integer with a single dot?
(5 answers)
Closed 6 years ago.
You can do
"a".charAt(0);
wouldn't it be nice if you could do:
42.isMeaningOfLife();
well, or rather something more practical like
myNumber.round();
Sure the first thing that crossed my mind is that this would be a performance hog but apparently that is not how the JS compiler works. Check this MDN article on JS strings:
Note that JavaScript distinguishes between String objects and
primitive string values. (The same is true of booleans and numbers.)
String literals (denoted by double or single quotes) and strings
returned from String calls in a non-constructor context (i.e., without
using the new keyword) are primitive strings. JavaScript automatically
converts primitives to String objects, so that it's possible to use
String object methods for primitive strings. In contexts where a
method is to be invoked on a primitive string or a property lookup
occurs, JavaScript will automatically wrap the string primitive and
call the method or perform the property lookup.
I believe it's a simple matter of supported syntax. Both, strings and numbers are wrapped in their respective object wrapper (String, Number) when performing objects operations on them.
Number.prototype.isTheMeaningOfLife = function () {
return this.valueOf() === 42;
};
(42).isTheMeaningOfLife(); //true
42.0.isTheMeaningOfLife(); //true

Categories

Resources