Domanda

I don't understand the Writable and Configurable attributes of Objects. For example, in the MDN for Object.prototype, there is a table where I can clearly see that Configurable, Writable and Enumerable Property Attributes of Object.prototype are locked.

However, I can write and extend Object.prototype, for example with the following code:

// Example 1
Object.prototype.testing=999;
console.log(Object.testing); // 999

// Example 2
var o = {};
console.log(o.testing); // 999
È stato utile?

Soluzione

What the MDN is referring to is the property prototype of Object itself. You cannot overwrite Object.prototype itself. If you try and make Object.prototype undefined, that will fail:

Object.prototype = 1;
console.log(Object.prototype); // [object Object]

If you try this in strict mode, you will get a TypeError upon attempting to assign to a non-writable property:

'use strict';
Object.prototype = 1; // TypeError: Cannot assign to read only property 'prototype' of function Object() { [native code] }

You can write to an object's own properties without changing what the object's reference is, and those have separate attributes. For example, see this:

var descriptor = Object.getOwnPropertyDescriptor(Object.prototype, 'toString');

console.log(descriptor.writable); // true
console.log(descriptor.enumerable); // false
console.log(descriptor.configurable); // true

There is a separate [[Extensible]] internal property that prevents the creation of new properties on an object -- this is set to false if you call Object.preventExtensions, Object.seal or Object.freeze.

Note that it's not a good idea to call Object.freeze on something like Object.prototype, as really weird things can happen:

Object.freeze(Object.prototype);
var building = {};
building.name = 'Alcove Apartments';
building.constructor = 'Meriton Apartments Pty Ltd';
console.log(building.constructor); // function Object() { [native code] } 

Just like the previous example, it will also throw a TypeError in strict mode.

Basically, even though it would be a property on the object itself, it uses the attributes from the prototype chain to check whether or not it can assign the property. This has been considered as a mistake in the language by some people, however others consider this behaviour to be by design.

Altri suggerimenti

From: http://ejohn.org/blog/ecmascript-5-objects-and-properties/

Writable: If false, the value of the property can not be changed.

Configurable: If false, any attempts to delete the property or change its attributes (Writable, Configurable, or Enumerable) will fail.

Enumerable: If true, the property will be iterated over when a user does for (var prop in obj){} (or similar).

The Writable, Enumerable and Configurable attributes in MDN appear to be about the Object.prototype object itself, not its properties.

So, what that means is that you can't replace Object.prototype with a different object, but you are allowed to add properties to it.

So, what that means is if you do this:

Object.prototype = {foo: "whatever"};   // doesn't work - is just ignored
var j = {};
console.log(j.foo);   // undefined

Then, the first line of code won't do anything.

I can clearly see that Configurable, Writable and Enumerable Property Attributes of Object.prototype are locked. However, I can write Object.prototype.

No. The writability only concerns the prototype property of the Object object:

Object.prototype = {}; // Error: Invalid assignment (in strict mode)
                       // simply fails in lax mode

And I can extend Object.prototype

Yes. You can extend the Object.prototype object (regardless how you refer to it); that's a different attribute (of the object, not of a single property):

var proto = Object.getPrototypeOf({});
proto.testing1 = 9999; // works
Object.preventExtensions(proto);
proto.testing2 = 9999; // Error: Invalid assignment (in strict mode)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top