当由defineProperty定义原型obj时,具有相同属性的hasOwnProperty会出错,为什么?

问题描述

代码如下:

function def(obj,key) {
  var val = obj[key];
  Object.defineProperty(obj,key,{
    enumerable: true,configurable: true,get: function reactiveGetter() {
      return val
    },set: function reactiveSetter(newVal) {
      val = newVal;
    }
  })
}

var AA = Object.create({});
AA.a = 1;
def(AA,"a")
var BB = Object.create(AA);
BB.a= 3;
BB.hasOwnProperty("a") == false // why ?

谢谢

解决方法

与数据属性不同,如果对象的原型链中具有 accessor属性,该对象将被调用(在该对象的上下文中),而不是在其上创建新属性对象本身。

换句话说,BB.a = 3会调用AA.a的setter,而不会创建属性BB.a

规范的相关部分是9.1.9.2 OrdinarySetWithOwnDescriptor部分。

演示:

var AA = {
  set a(value) {
    console.log('AA','value:',value,'this:',this === AA ? 'AA': 'BB');
  }
}
AA.a = 21;
var BB = Object.create(AA);
BB.a = 42;
console.log(BB.a);