我正在使用Object.create
创建一个对象,我想为其添加属性。
> var o = Object.create({});
undefined
> Object.defineProperty(o, "foo", {value: 43, enumerable: true});
{foo: 43}
> o
{foo: 43}
> o.foo
43
> for (var i in o) { console.log(i); }
foo
> Object.keys(o)
['foo']
> Object.defineProperty(o, "foo", {value: 43, enumerable: false });
TypeError: Cannot redefine property: bar
Q1)为什么我不能重新定义财产?
> o.__proto__
{}
> o.prototype
undefined
Q2)为什么原型是空的?为什么这两个值不同,即{}
vs undefined
?
答案 0 :(得分:43)
您无法重新定义该属性,因为Object.defineProperty()
默认为不可配置的属性,来自docs:
配置
当且仅当可以更改此属性描述符的类型并且可以从相应对象中删除属性时,才返回true。 默认为false。
因此默认为false - 您需要将其传递给configurable: true
以允许它。
答案 1 :(得分:29)
默认情况下,Object.defineProperty()
定义的属性为non-configurable
。
要允许重新定义或重新配置它们,必须使用此属性设置为true
来定义它们。
var o = Object.create({});
Object.defineProperty(o, "foo", {
value: 42,
enumerable: true,
configurable: true
});
console.log(o); // { foo: 42 }
Object.defineProperty(o, "foo", {
value: 45,
enumerable: true,
configurable: true
});
console.log(o); // { foo: 45 }
o.prototype
为undefined
,因为对象通常不具有prototype
属性。
这些属性可以在构造函数function
上找到new
个实例继承,大致相当于:
function Foo() {}
// ... = new Foo();
var bar = Object.create(Foo.prototype);
Foo.call(bar);
然而,对象知道它们的原型对象。它们是通过internal [[Prototype]]
property引用的,__proto__
是非正式的获取者/设置者:
console.log(o.__proto__); // {}
阅读[[Prototype]]
的标准化方法是使用Object.getPrototypeOf()
:
console.log(Object.getPrototypeOf(o)); // {}
答案 2 :(得分:1)
仅当可写和可配置均为假时,才会发生“无法重新定义属性”。
如果可写或可配置为真,错误将消失。
"use strict"
var obj = {};
Object.defineProperty(obj, "name",
{
value: "Fundebug",
writable: false,
configurable: false
})
Object.defineProperty(obj, "name",
{
value: "云麒"
}) // “Uncaught TypeError: Cannot redefine property: name”
因此,jdphenix和Jonathan并不完全正确。
答案 3 :(得分:0)
Object.defineProperty(o, "foo", {value: 43, enumerable: true});
此行定义对象foo
的属性o
,值:43,以及属性enumerable:true
,writable:false
,configurable:false
。如果属性存在,则defineProperty
更新其标志。否则,它将使用给定的值和标志创建属性;在这种情况下,如果未提供标志,则将其假定为 false 。
因此,这里我们将属性设为不可配置,因为configurable
标志(或属性)为 false 。
制造物业
non-configurable
是一条单向路。我们不能改变 并以defineProperty
返回。准确地说,不可配置性对 defineProperty:
因此请谨慎使用configurable
中的defineProperty
标志,如果要更改 enumerable 和 writable 属性,请务必在defineProperty中将其设置为true (或标志)。 一旦设置了可配置的false,就无法将其设置为true。