[英]Why can't I redefine a property in a Javascript object?
我正在使用Object.create
创建一个 object,我想向它添加属性。
> 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)为什么原型是空的? 为什么这两个值不同,即{}
与undefined
?
您无法重新定义该属性,因为Object.defineProperty()
默认为不可配置的属性,来自文档:
可配置
当且仅当可以更改此属性描述符的类型并且可以从相应的对象中删除该属性时,才为 true。 默认为假。
所以这默认为 false - 您需要将它传递给configurable: true
以允许它。
默认情况下,通过Object.defineProperty()
定义的属性是不可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);
然而,对象知道它们的原型对象。 它们是通过内部[[Prototype]]
属性引用的,其中__proto__
是/曾经是以下的非官方 getter/setter:
console.log(o.__proto__); // {}
读取[[Prototype]]
的标准化方法是使用Object.getPrototypeOf()
:
console.log(Object.getPrototypeOf(o)); // {}
只有当writable和configure都为 false 时,才会发生“无法重新定义属性”。
如果可写或可配置为真,错误就会消失。
"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 并不完全正确。
Object.defineProperty(o, "foo", {value: 43, enumerable: true});
这一行定义了对象o
上的属性foo
,其值为:43 和属性enumerable:true
、 writable:false
、 configurable:false
。 如果该属性存在,则defineProperty
更新其标志。 否则,它会创建具有给定值和标志的属性; 在这种情况下,如果未提供标志,则假定为false 。
因此,在这里我们使我们的属性不可配置,因为可configurable
标志(或属性)为false 。
使属性
non-configurable
是一条单向之路。 我们不能用defineProperty
把它改回来。准确地说,不可配置性对defineProperty施加了几个限制:
所以要小心defineProperty
可configurable
标志,如果要更改可枚举和可写属性(或标志),请始终在defineProperty
中将其设置为true。 一旦您设置了可配置的 false,您就无法将其设置为 true。
一个可能的原因可能是您的版本问题。 Node 10 不允许实时绑定,但较新的版本现在允许这样做。 请检查您是否在节点 12 或以上。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.