Can you explain how the JavaScript expression:
[1 [{}]]
parses/evaluates? In Firefox, Chrome, Konqueror, and rhino, it seems to create an array with a single element, undefined
. However, I don't understand why.
In Firefox:
[1 [{}]].toSource()
produces
[(void 0)]
Replacing 1 with other JavaScript values seems to yield the same result.
Update: I think I understand now. codeka, Adrian, and CMS clarified things. As far as the standard, I tried to walk through ECMAScript 5.
1 [{}]
is a Property Accessor, so it's covered in §11.2.1.baseReference
is the result of evaluating1
, so still1
.baseValue = GetValue(baseReference) == 1
.- At
GetValue
(§8.7.1),Type(1)
is notReference
(a resolved name binding), so return 1. propertyNameReference
is result of evaluating{}
, so an empty object.propertyNameValue = GetValue(propertyNameReference) == {}
- At
CheckObjectCoercible(baseValue)
(§9.10), we return (Number is object-coercible). propertyNameString = ToString(propertyNameValue)
- At
ToString
(§9.8), returnToString(ToPrimitive({}, hint String))
- At
ToPrimitive
(§9.1), return result of object's[[DefaultValue]]
, passingPreferredType
(string). - At
[[DefaultValue]]
(§8.12.8), let toString be result of[[Get]]
with argumenttoString
. - This is defined at §15.2.4.2 to return
"[object " + [[Class]] + "]"
, where[[Class]]
is "Object" for the default object prototype. - Since there is a callable
toString
, we call it with argumentthis
being{}
. - Return a value of type
Reference
, whose base value isBaseValue
(1) and whose referenced name ispropertyNameString
("[object Object]"
).
We then go to Array initializer (§11.1.4), and construct a single element array with the result.
Reading the OP and Nick comments, I think I can expand a little bit more the Adrian's answer to make it clearer.
It's perfectly valid JavaScript.
JavaScript handles object property names as strings, objects cannot contain other types or other objects as keys, they are just strings.
The bracket notation property accessor (
MemberExpression [ Expression ]
) implicitly converts the expression between brackets into a string, so:In the above example you can see that I assign a value to the
{}
property, and{}.toString()
(or{}+''
) produces the string"[object Object]
(viaObject.prototype.toString
).The expression
1 [{}]
implicitly converts the 1Number
primitive to an object (this is made by the property accessor) and it lookups a property named"[object Object]"
the property lookup is made on theNumber.prototype
and theObject.prototype
objects, for example:Finally, the
1 [{}]
expression is itself enclosed in brackets ([1 [{}]]
), this is actually an Array literal.In conclusion here is how the parser evaluates the expression:
If we break it up a bit, you'll see:
I believe it's valid JavaScript, but I'm not an expert...
It is because you are trying to get the property
{}
of the object1
and then place it in an array.1
doesn't have the property{}
, so1[{}]
isundefined
.If you replace the
1
with an array, you will see how it is working. With1
as[5]
and{}
as0
, it is[[5][0]]
.Also, keep in mind that
obj['property']
is the same asobj.property
.