我不理解Objects的可写和可配置属性属性

时间:2014-04-09 11:00:30

标签: javascript object prototype

我不理解Objects的Writable和Configurable属性。例如,在Object.prototype的MDN中,有一个表格,我可以清楚地看到 Object.prototype 的可配置,可写和可枚举的属性属性被锁定。

但是,我可以编写和扩展Object.prototype,例如使用以下代码:

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

// Example 2
var o = {};
console.log(o.testing); // 9999

4 个答案:

答案 0 :(得分:3)

MDN所指的是prototype本身的属性Object。您无法覆盖Object.prototype本身。如果您尝试使Object.prototype未定义,则会失败:

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

如果您在严格模式下尝试此操作,则在尝试分配给不可写属性时,您将获得TypeError

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

您可以在不更改对象引用的内容的情况下写入对象自己的属性,并且这些属性具有单独的属性。例如,请看:

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

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

有一个单独的[[Extensible]]内部属性阻止在对象上创建新属性 - 如果您拨打falseObject.preventExtensions或者Object.seal,则设置为Object.freezeObject.freeze

请注意,在Object.prototype之类的内容上调用Object.freeze(Object.prototype); var building = {}; building.name = 'Alcove Apartments'; building.constructor = 'Meriton Apartments Pty Ltd'; console.log(building.constructor); // function Object() { [native code] } 并不是一个好主意,因为可能会发生奇怪的事情:

TypeError

就像前面的例子一样,它也会在严格模式下抛出{{1}}。

基本上,即使它是对象本身的属性,它也会使用原型链中的属性来检查它是否可以分配属性。有些人在语言中已经considered as a mistake,但是其他人认为这种行为是设计的。

答案 1 :(得分:3)

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

Writable:如果为false,则无法更改属性的值。

可配置:如果为false,任何删除属性或更改其属性(Writable,Configurable或Enumerable)的尝试都将失败。

Enumerable:如果为true,则当用户执行(var ob in obj){}(或类似)时,属性将被迭代。

答案 2 :(得分:2)

  

我可以清楚地看到Object.prototype的Configurable,Writable和Enumerable属性属性被锁定。   但是,我可以写Object.prototype

没有。可写性仅涉及prototype对象的Object属性:

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

我可以延长Object.prototype

是。您可以扩展Object.prototype对象(无论您如何引用它);那是different attribute(对象的,而不是单个属性):

var proto = Object.getPrototypeOf({});
proto.testing1 = 9999; // works
Object.preventExtensions(proto);
proto.testing2 = 9999; // Error: Invalid assignment (in strict mode)

答案 3 :(得分:1)

MDN中的可写,可枚举和可配置属性似乎与Object.prototype对象本身有关,而不是其属性。

所以,这意味着你不能用另一个对象替换Object.prototype,但是你可以向它添加属性。

那么,这意味着如果你这样做:

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

然后,第一行代码将不会执行任何操作。