I don't understand writable and configurable property attributes of Objects

后端 未结 4 946
我在风中等你
我在风中等你 2021-01-19 11:10

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

相关标签:
4条回答
  • 2021-01-19 11:20

    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)
    
    0 讨论(0)
  • 2021-01-19 11:26

    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.

    0 讨论(0)
  • 2021-01-19 11:27

    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.

    0 讨论(0)
  • 2021-01-19 11:36

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

    0 讨论(0)
提交回复
热议问题