On IE __proto__ test cases
Yeah, these test all look incorrect to me. IE11 implements an older draft where __proto__
was a magic property.
on 3.1.1-10 AFAIK Object.preventExtension({})
makes proto immutable.
Since Object.freeze({})
includes that preventExtension
call, immutable
should be so no y
inherited there.
From: Erik Arvidsson
Yeah, these test all look incorrect to me. IE11 implements an older draft where
__proto__
was a magic property.
That’s right. Our implementation predates the May spec updates that changed the spec for __proto__
. We will update the test contributions to tests262 to align with the updated spec.
One question from looking at implications of this change. Is it intentional that there is no longer a way to remove (or customize) the special handling of __proto__
in object literals?
delete Object.prototype.__proto__
var p = { y: 34 }
var o = { x: 42, __proto__: y }
o.y === 34 // was false, now true
Yes, that was intentional. Even though the __proto__:
looks related to
the __proto__
property initially on Object.prototype
, that's only
cosmetic. It is now simply part of the object literal syntax, in just the
same way that <|
used to just be special syntax.
This does seem to leave a hole in the functionality compared to <|
, which
is, how do you create a normal property named __proto__
. The answer is
the computed property syntax: {["__proto__"]: ...}
.
I don't remember what whether we decided that {"__proto__": ...}
means the
same thing as {["__proto__"]: ...}
or {__proto__: ...}
. I think we decided
the second, which probably better follows the principle of least surprise.
OTOH, the first would have kept JavaScript closes to JSON.
On Jul 11, 2013, at 9:33 PM, Mark S. Miller wrote:
Yes, that was intentional. Even though the
"__proto__:"
looks related to the"__proto__"
property initially onObject.prototype
, that's only cosmetic. It is now simply part of the object literal syntax, in just the same way that<|
used to just be special syntax.
Agreed, this is intentional.
This does seem to leave a hole in the functionality compared to
<|
, which is, how do you create a normal property named__proto__
. The answer is the computed property syntax:{["__proto__"]: ...}
.I don't remember what whether we decided that
{"__proto__": ...}
means the same thing as{["__proto__"]: ...}
or{__proto__: ...}
. I think we decided the second, which probably better follows the principle of least surprise. OTOH, the first would have kept JavaScript closes to JSON.
There are various possible issues here. First, as the spec. is now written {__proto__: ...}
and {"__proto__":...}
mean exactly the same thing.
Also, I think we still have an issue as to whether or not we want to allow computed property keys (in propName positions) to produce string-valued keys. When we first were considered computed propNames there were some objections (Ollie Hunt??) to allowing string values. My recollection was that it potentially forced turning the static checks for things like duplicate property names in object literals into dynamic checks. My fuzzy recollection is that at that time we decided to disallowed string valued computed propNames (this is before we temporarily eliminated computed propNames in favor of at-names). I think there was some discussion of this at the last meeting but I don't feel that we have adequate re-explored the earlier decisions (?) to not allow string valued propName. So, in the current draft I only allow Symbol valued computed propNames but have it marked as a open issue.
If I turn on string valued computed propNames in the spec, then as currently written {__proto__: ...}
and {["__proto__"]: ...}
will have the same meaning. We can, of course, change that but it will significant complicate the delta spec. needed in Annex B for __proto__
in object literals.
finally, note that the current spec. only assigns special meaning to __proto__
for the production:
PropertyDefinition: PropertyName : AssignmentExpression
that means that things like:
let __proto__= { };
( {__proto__})
and
({__proto__ (arg) {}})
produce object with regular own properties named "__proto__"
.
So, there are standard tests now for ES6!
I'd like to discuss some of the
__proto__
tests.3.1.1-10
Object.freeze(Object.prototype)
disables__proto__
function testcase() { Object.freeze(Object.prototype); var a = new Object(); a.__proto__ = { y: 2 }; return a.y === undefined; }
I'm not sure I see why this test should succeed. Freezing "a" should prevent its [[Prototype]] from being changed, but I don't see why it would be the case for
Object.prototype
.(same for 3.1.1-9 for
Object.seal
)3.1.1-11 [[DefineOwnProperty]] UnderScoreProtoEnabled is set to true when
Object.prototype
is set with default valuesfunction testcase() { Object.defineProperty(Object.prototype, "__proto__", { writable: true, enumerable: false, configurable: true }); var obj = {}; obj.__proto__ = { x: 10 }; return obj.x === 10; }
I don't fully understand this test case. I think that overriding
Object.prototype.__proto__
with a data attribute should remove its magic.(same for 3.1.1-7, 3.1.2-4-1+bcd )
3.1.1-4
Object.prototype.__proto__
is data property with{writable:true, enumerable:false, configurable:true, value:null}
attributesfunction testcase() { var desc = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__"); return desc.writable === true && desc.enumerable === false && desc.configurable === true && desc.value === null; }
... hmm... I admire the sense of humor of whoever wrote that test. TC39 Meeting notes from May 2013:
3.1.1-6 Modification of
Object.prototype.__proto__
causes UnderScoreEnabled to be set to false. Setting it to{}
function testcase() { Object.defineProperty(Object.prototype, "__proto__", {}); var obj = new Object(); obj.__proto__ = { y: 2 }; return obj.y === undefined; }
I believe the
Object.defineProperty
line is a no-op, so the test should fail.3.1.2-2-14b [[Put]]
__proto__
with value{y:2}
onwindow
objectfunction testcase() { window.__proto__ = { y: 2 }; return window.y === undefined; }
window
is not part of ECMAScript. This test might as well throw aReferenceError
. As far as the global object, I don't think it's status on [[Prototype]] is very clear from a standard standpoint, so I would recommend not having tests for that.I only looked at the tests failing in Firefox, there are probably other errors. It would be good if the tests were reviewed carefully before becoming part of any sort of "conformance" test suite.