最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Object.preventExtensions actually allows mutation of __proto__? - Stack Overflow

programmeradmin1浏览0评论

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)?

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)?

Share Improve this question edited Dec 28, 2011 at 22:25 Tom van der Woerdt 30k7 gold badges74 silver badges105 bronze badges asked Jun 8, 2011 at 15:26 pimvdbpimvdb 155k80 gold badges311 silver badges356 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

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 bees 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

In ECMAScript 5, objects have a boolean internal property named [[Extensible]], this property is set to false when you call the Object.preventExtensions method, and after that, no new own properties can be added to the object.

On Chrome 14.0.786.0, the assignment to __proto__ throws a TypeError as you expect.

But remember that the __proto__ extension is non-standard, so it's behavior may vary, of course syntactically it is a "property assignment", but internally it doesn't "add an own property", it mutates the object's prototype, thing that is not possible to do by any standard method.

About the example of the Object.getPrototypeOf method you show us, it's simply retrieving the object's prototype, in the case of your fixed object, it's the Object.prototype object:

Object.getPrototypeOf(fixed) === Object.prototype; // true

So your example:

Object.getPrototypeOf(fixed).oh = 'hai'

Is equivalent to:

Object.prototype.oh === 'hai';
发布评论

评论列表(0)

  1. 暂无评论