change behavior of Array.prototype.push?
That just means anyone relying on that behavior is broken in Firefox - if their code would work in all of the other browsers, then it's a Firefox bug, not something the spec can change.
Note that you can also observe this behavior with:
Array.prototype.push.call(Object.defineProperty({}, '0', { set: function (v) { throw v; } }), 1)
which does correctly throw for me in Firefox,
Safari, and Chrome.
Similarly, I do see that Object.defineProperty(Object.prototype, '0', { set: function (v) { throw v; } }); [].push(1)
and
Object.defineProperty(Array.prototype, '0', { set: function (v) { throw v; } }); [].push(1)
also fail to throw in Firefox, but do correctly throw in
Safari and Chrome.
In other words, changing the spec here would make code that depends on the
lookup on the receiver fail, including the code above - Firefox's bug is
solely that it doesn't work when the receiver inherits from
Object.prototype
or Array.prototype
, and Object.prototype
or
Array.prototype
has been modified.
Please do file this Firefox bug ASAP, so they can correct it.
On Sat, Oct 29, 2016 at 03:15:48PM -0700, Jordan Harband wrote:
That just means anyone relying on that behavior is broken in Firefox - if their code would work in all of the other browsers, then it's a Firefox bug, not something the spec can change.
But apparently, nobody's stuff broke. In the Linux kernel, the approach to API changes is basically "you can change things as long as no existing userspace code breaks because of those changes", which I think is reasonable. And as far as I can tell, ECMAScript uses a similar approach; for example, AFAIK in ECMAScript 6.0, the following code would have worked, but ECMAScript 7.0 breaks it (by making %ObjectPrototype% an immutable prototype exotic object):
Reflect.setPrototypeOf(Object.prototype, {__proto__:null, a:1});
console.log(({}).a);
So clearly, reasonable breakage in new ECMAScript versions is permitted.
What do you mean by “nobody’s stuff broke”?
I would be surprised if nothing broke if v8 or JavaScriptCore or Chakra switched to the FireFox approach (which is only broken in the specific case where the target is a JSArray, based on what Jordan is saying). If you can prove that nothing breaks if other browsers implement that change (and, if similar changes are implemented for pop/shift/unshift, since IMHO those apis need to behave consistently), then maybe it’s not an unreasonable change.
On Sat, Oct 29, 2016 at 07:40:56PM -0400, Caitlin Potter wrote:
What do you mean by “nobody’s stuff broke”?
I mean "nobody seems to have complained yet, so there can't be that many people who rely on the specced behavior".
I would be surprised if nothing broke if v8 or JavaScriptCore or Chakra switched to the FireFox approach (which is only broken in the specific case where the target is a JSArray, based on what Jordan is saying). If you can prove that nothing breaks if other browsers implement that change
Nope, I can't, and I assume that nobody was able to prove that making Object.prototype.[[Prototype]] immutable wouldn't break anything either. However, I think that it's pretty clear that, if such a change is only made for arrays inheriting from %ArrayPrototype%, someone would have to do some pretty weird stuff to actually run into this edgecase.
(and, if similar changes are implemented for pop/shift/unshift, since IMHO those apis need to behave consistently),
Yeah, I guess so.
On 10/29/16 6:15 PM, Jordan Harband wrote:
Please do file this Firefox bug ASAP, so they can correct it.
Hello!
At the moment, Array.prototype.push is (afaics) specified so that it leaks property accesses to Array.prototype, as can be seen in V8/Chrome:
I think that's bad. Luckily, Firefox doesn't implement it in a spec-compliant way:
... and nobody seems to have noticed, so changing the spec shouldn't break things for anyone. So, would it be possible to specify Firefox' behavior and deprecate the currently specified one?