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 Configur
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)
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.
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.
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).