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 badges2 Answers
Reset to default 5Nope, 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';
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745535181a4631873.html
评论列表(0条)