我错误地使用了Object.defineProperty
,将函数作为其描述符参数传递,就像下面的代码一样:
let fakeDesc = () => {}
let obj = {
method1: function() {
console.log('this is method1');
}
};
Object.defineProperty(obj, 'method1', fakeDesc);
obj.method1();
代码评估结果是method1
未被覆盖。
根据 MDN 文档( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty )
If a descriptor has neither of value, writable, get and set keys, it is treated as a data descriptor.
所以我认为fakeDesc
应该像数据描述符一样对待,并且默认value
属性应该是未定义
,所以上面的代码将导致 obj.method1
等于 undefined
。
这种情况怎么样?有没有一些文档可以解释这个问题?
最佳答案
传递的描述符(第三个参数)应该是一个普通对象,具有value
和writable
等属性。如果您传递函数而不是对象,它将被忽略。
A data descriptor is a property that has a value, which may or may not be writable.
如果您传递函数,则不会传递数据描述符。
如果您传递一个带有 fakeDesc
的 value
属性的对象,它将按预期工作:
let fakeDesc = () => {}
let obj = {
method1: function() {
console.log('this is method1');
}
};
Object.defineProperty(obj, 'method1', { value: fakeDesc });
obj.method1();
当您传递没有 value
属性的对象时,基础值不会更改,尽管该属性上的描述符可能会更改。例如,以下代码将 method1
上的 enumerable
更改为 false
,尽管没有更改基础值(this is method1
函数):
let obj = {
method1: function() {
console.log('this is method1');
}
};
console.log(Object.getOwnPropertyDescriptor(obj, 'method1'));
Object.defineProperty(obj, 'method1', { enumerable: false });
console.log(Object.getOwnPropertyDescriptor(obj, 'method1'));
我想您可以技术上传递一个函数并让它更改描述符,但是您必须直接在函数上设置一个属性,这真的很奇怪:
const fakeFn = () => {};
fakeFn.enumerable = false;
let obj = {
method1: function() {
console.log('this is method1');
}
};
console.log(Object.getOwnPropertyDescriptor(obj, 'method1'));
Object.defineProperty(obj, 'method1', fakeFn);
console.log(Object.getOwnPropertyDescriptor(obj, 'method1'));
obj.method1();
当 MDN 表示不同键(例如 configurable
和 enumerable
)的默认值为 false
时,的默认值为
code>value
为 false
,它指的是当您创建对象上尚不存在的属性时的过程。该进程定义于 DefineOwnProperty .
关于JavaScript Object.defineProperty 无法按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55096737/