说我有一个对象:
Object.defineProperty(Agent.prototype, 'id', {
configurable: false,
writable: false
})
当我构建Agent类时,我决定使id属性不可变:
this
但在某些时候我会想要删除对象。而且因为我们实际上无法删除id
,所以我将通过删除Object.defineProperty(agent, 'id', {
configurable: true,
writable: true
})
delete agent.id
属性来削弱对象。所以我再去写一下这个属性:
TypeError: Cannot redefine property: id
但我当然得到:
id
因为{{1}}已经存在。
如何使现有不可写属性可写?
答案 0 :(得分:7)
当属性已存在时,Object.defineProperty()会尝试 根据描述符中的值修改属性 对象的当前配置。如果旧的描述符有它的 可配置属性设置为false(该属性据说是 “不可配置”),那么除了可写之外没有任何属性可以 改变。如果属性是不可配置的,则其可写属性可以 只能改为假。
换句话说,如果要稍后修改属性定义(可写),则必须在第一个属性定义中将configurable
设置为true
。
请注意,当configurable
为false
时,您可以采用另一种方式(使可写属性不可写),但这与您在此处所做的相反。
答案 1 :(得分:5)
有一种方法可以用你的具体例子来做到这一点!然而,它非常顽皮。可以自行决定在生产代码中使用它。
这里的问题不仅是non-configurable
属性不是,也是可配置的 - 当你调用Object.defineProperty
时,它会检查对象上的现有属性。对象的原型链。
解决这个问题很简单:暂时摆脱原型链!
警告: 修改现有对象的原型链是一项危险的操作,只能在成人监督下进行。副作用可能包括:严重的重新编译,减少应用程序范围的性能,以及在清醒的审查员的大多数代码审查程序中自动F.
let parent = {};
Object.defineProperty(parent, "property", {
get: () => 1,
configurable: false
});
// here child.property === 1 of course
let child = Object.create(parent);
// however, if we like abusing our JavaScript engine, we can do this:
Object.setPrototypeOf(child, null);
Object.defineProperty(child, "property", {
get: () => 2,
configurable: true
});
Object.setPrototypeOf(child, parent);
//now child.property === 2!
在您的情况下,属性是在Agent
的原型上定义的,而不是Agent
对象本身。因此你可以使用这个技巧。新属性将掩盖旧属性,将替代使用。旧的财产仍然存在,只会被阻止。