I was browsing MDC about new functions added to Object. One of them, Object.preventExtensions
, is said to prevent mutations to the object's prototype, which can be obtained by using Object.getPrototypeOf
or __proto__
.
On Chrome, however, it seems to simply allow mutations to the object's prototype. This can be confirmed by just executing the code on the relevant page:
// EXTENSION (only works in engines supporting __proto__
// (which is deprecated. Use Object.getPrototypeOf instead)):
// A non-extensible object's prototype is immutable.
var fixed = Object.preventExtensions({});
fixed.__proto__ = { oh: "hai" }; // throws a TypeError
I don't get this TypeError
, and fixed.__proto__.oh === 'hai'
, so it has been set even though it should have been disallowed. I can also add it when coding like Object.getPrototypeOf(fixed).oh = 'hai'
.
Does this mean Chrome has a different interpretation of this function? How can one prevent extensions to an object's prototype (in Chrome)?
Nope, Chrome and Mozilla both implement the standards part of the spec the same. Read carefully:
Object.preventExtensions
only prevents addition of own properties. Properties can still be added to the object prototype.
Everything to do with .__proto__
is non-standard, and Chrome can implement that differently. You showed only that Chrome implements details with .__proto__
differently, and in my opinion, more intuitively: The spec says that the prototype is still extensible, so it makes sense that you should still be able to mutate it. The question then becomes why did Mozilla implement it that way?
For example, the following code works the same on both Chrome and FF:
var fixed = Object.preventExtensions({});
Object.getPrototypeOf(fixed).p = 99;
fixed.p; // 99
Clearly the prototype is still mutable. That makes sense with Chrome's implementation of .__proto__
.
So to prevent extensions of a prototype, do so separately:
var fixed = Object.preventExtensions({});
Object.preventExtensions(Object.getPrototypeOf(fixed));
Object.getPrototypeOf(fixed).p = 99; // TypeError: Can't add property p, object is not extensible