JavaScript Object.defineProperty无法正常工作

时间:2019-03-11 07:07:39

标签: javascript

我错误地将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

  

如果描述符没有值,不可写,获取和设置键的值,则将其视为数据描述符。

所以我认为fakeDesc应该像数据描述符一样对待,并且默认的value属性应该是undefined,所以上面的代码将导致obj.method1等于undefined

这种情况如何?并有一些文档可以解释这个问题吗?

1 个答案:

答案 0 :(得分:2)

传递的描述符(第三个参数)应该是具有诸如valuewritable之类的普通对象。如果传递 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函数的基础值),但以下falsemethod1更改为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表示不同键(例如configurableenumerable)的默认值为false,而value的默认值为{{1} },是指创建对象上不存在的属性时的过程 。该过程在DefineOwnProperty中定义。