On Feb 15, 2013, at 6:30 PM, Jeff Walden wrote:
> Consider:
>
> Object.defineProperty(Object.prototype, "0", { value: 17, writable: false,
> configurable: false });
> [].push(42);
>
> Per ES5, I think this is supposed to throw a TypeError. The push should be
> setting property "0" with Throw = true, which means that when [[CanPut]]
> fails, a TypeError gets thrown. No engine I can test does this, I suspect
> because everyone's mis-implemented an optimization.
Right, ES5 carefully put in all those Throw = true's, to account for exactly
those situations. Did you also test for non-writable and accessor properties
on an actual Array instance.
Did you try this on IE9/10 (I don't have copies available with me right now).
All the other browsers had implementations of push and other Array methods
that predate ES5, so it is conceivable that those implementations have not been
updated to match the spec. IE9, on the other-hand, was a new implementation
that post dates ES5 and was supposed to be following the spec.
I'm shocked if Test262 doesn't include any tests for these situations. I'm
remember including them in a list of things that needed to be tested for all of
the Array methods that was handed off to the team that wrote the Test262 tests.
>
> On IRC it was pointed out that
> http://wiki.ecmascript.org/doku.php?id=strawman:fixing_override_mistake is
> supposed to fix this: you should be able to shadow a non-writable property on
> a prototype. Or something. But there's contention there about this not
> actually being a mistake. (I think that contention's probably right, for
> what it's worth, but I digress.)
>
> But suppose it isn't, for the moment. What then of this:
>
> Object.defineProperty(Object.prototype, 0, { set: function() { throw "FAIL";
> } });
> [].push(42)
>
> I think this should throw, again because it's *setting* property "0". But
> again, no engine I can test actually throws for this.
>
> My gut says this is a case where every engine attempted to optimize, and
> optimized wrongly such that incorrect semantics resulted. The question is,
> since no engine's following the spec, whether the spec should change, the
> engines should change, or what. Given that indexed properties on
> Array.prototype and Object.prototype are not something anyone sane does, I
> tend to think changing it to [[DefineOwnProperty]] would be good. But maybe
> the spec really should win, and everyone should change. I dunno. Please
> sort this out! :-)
Prior to ES5, implementations were doing various random things for the edge
cases of accessor properties in arrays. ES5 now tells them what they are
supposed to do.
Note that implementation bugs aren't just in the Array methods and don't
require access to inherited properties. I just tried the following in a FF18
scratch pad:
var a = []
Object.defineProperty(a, "1", {
get: function() {throw "get"; return "got 1"},
put: function(v) {throw "put"+v},
configurable: true});
a[1]
/*
Exception: get
*/
a[1]=0
/*
0
*/
var a = []
Object.defineProperty(a, "1", {
get: function() {throw "get"; return "got 1"},
put: function(v) {throw "put"+v},
configurable: true});
a[1]
/*
Exception: get
*/
a[1]=0
/*
0
*/
var a = []
Object.defineProperty(a, "1", {
get: function() {throw "get"; return "got 1"},
put: function(v) {throw "put"+v},
configurable: true});
a[1]
/*
Exception: get
*/
a[1]=0
/*
0
*/
var a = []
Object.defineProperty(a, "1", {
get: function() {throw "get"; return "got 1"},
put: function(v) {throw "put"+v},
configurable: true});
a[1]
/*
Exception: get
*/
a[1]=0
/*
0
*/
var a = []
Object.defineProperty(a, "1", {
get: function() {throw "get"; return "got 1"},
put: function(v) {throw "put"+v},
configurable: true});
a[1]
/*
Exception: get
*/
a[1]=0
/*
0
*/
var a = []
Object.defineProperty(a, "1", {
get: function() {throw "get"; return "got 1"},
put: function(v) {throw "put"+v},
configurable: true});
a[1]
/*
Exception: get
*/
a[1]=0
/*
0
*/
var a = []
Object.defineProperty(a, "1", {
get: function() {throw "get"; return "got 1"},
put: function(v) {throw "put"+v},
configurable: true});
a[1]
/*
Exception: get
*/
a[1]=0
/*
0
*/
var a = []
Object.defineProperty(a, "1", {
get: function() {throw "get"; return "got 1"},
put: function(v) {throw "put"+v},
configurable: true});
a[1]
/*
Exception: get
*/
a[1]=0
/*
0
*/
var a = []
Object.defineProperty(a, "1", {
get: function() {throw "get"; return "got 1"},
put: function(v) {throw "put"+v},
configurable: true});
a[1]
/*
Exception: get
*/
a[1]=0
/*
0
*/
var a = []
Object.defineProperty(a, "1", {
get: function() {throw "get"; return "got 1"},
put: function(v) {throw "put"+v},
configurable: true});
a[1]
/*
Exception: get
*/
a[1]=0
/*
0
*/
var a = []
Object.defineProperty(a, "1", {
get: function() {throw "get"; return "got 1"},
put: function(v) {throw "put"+v},
configurable: true});
a[1]
/*
Exception: get
*/
a[1]=0
/*
0
*/
var a = []
Object.defineProperty(a, "1", {
get: function() {throw "get"; return "got 1"},
put: function(v) {throw "put"+v},
configurable: true});
a[1]
/*
Exception: get
*/
a[1]=0
/*
0
*/
var a = []
Object.defineProperty(a, "1", {
get: function() {throw "get"; return "got 1"},
put: function(v) {throw "put"+v},
configurable: true});
a[1]
/*
Exception: get
*/
a[1]=0
/*
0
*/
var a = []
Object.defineProperty(a, "1", {
get: function() {throw "get"; return "got 1"},
put: function(v) {throw "put"+v},
configurable: true});
a[1]
/*
Exception: get
*/
a[1]=0
/*
0
*/
Note that no exception was reported on the [[Put]] to the accessor.
Allen
var a = []
Object.defineProperty(a, "1", {
get: function() {throw "get"; return "got 1"},
put: function(v) {throw "put"+v},
configurable: true});
a[1]
/*
Exception: get
*/
a[1]=0
/*
0
*/
>
> Jeff
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss