我错误地将Object.defineProperty
用作传递其描述符参数的函数,就像打击代码一样:
let fakeDesc = () => {}
let obj = {
method1: function() {
console.log('this is method1');
}
};
Object.defineProperty(obj, 'method1', fakeDesc);
obj.method1();
代码评估结果是未覆盖method1
。
如果描述符没有值,不可写,获取和设置键的值,则将其视为数据描述符。
所以我认为fakeDesc
应该像数据描述符一样对待,并且默认的value
属性应该是undefined
,所以上面的代码将导致obj.method1
等于undefined
。
这种情况如何?并有一些文档可以解释这个问题吗?
答案 0 :(得分:2)
传递的描述符(第三个参数)应该是具有诸如value
和writable
之类的普通对象。如果传递 function 而不是对象,则它将被忽略。
数据描述符是具有值的属性,该值可以写也可以不写。
如果传递函数,则不会传递数据描述符。
如果您传递一个具有value
属性的fakeDesc
对象,它将按预期工作:
let fakeDesc = () => {}
let obj = {
method1: function() {
console.log('this is method1');
}
};
Object.defineProperty(obj, 'method1', { value: fakeDesc });
obj.method1();
当您传递不带value
属性的对象时,基础值不会改变,尽管该属性上的 descriptor 可能会改变。例如,尽管未更改(enumerable
函数的基础值),但以下false
从method1
更改为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
,而value
的默认值为{{1} },是指创建对象上不存在的属性时的过程 。该过程在DefineOwnProperty中定义。