JavaScript getter 运行 继承期间

JavaScript getter running during inheritance

我正在尝试使用 JavaScript getter 和继承,我 运行 喜欢这个有趣的行为。行尾的注释是语句打印的顺序。

function createFruit(size) {
   return {
      get size() {
         console.log('getting size'); // 2, 4
         return size;
      },
   };
}

function createApple(color) {
   let apple = {
      get color() {
         return color;
      },
   };

   return Object.assign(Object.create(apple), createFruit(2));
}


let small = createFruit(1);
console.log('calling getSize fruit'); // 1
console.log(small.size); // 3

let green = createApple('green');
console.log(green.color); // 5
console.log('calling getSize apple'); // 6
console.log(green.size); // 7
   

输出:

calling getSize fruit
getting size
1
getting size
green
calling getSize apple
2

混淆的部分是四、六、七的打印顺序。我的理解是 JavaScript 中的 getter 是惰性的,这意味着它们只在需要时被调用。在最后一行之前我不需要获得绿色的大小,但是在构建苹果时正在调用 getter 。为什么会这样?我怎样才能重写我的代码来避免这种行为?

附带说明一下,如果我使用的一般模式不适合执行此操作,请告诉我。

Object.assign 不会像 getter 函数那样复制 属性 属性,它使用它们来评估 属性 值并复制 that 到目标上。因此,在 createApple 调用期间,将调用 getter 并在 apple 对象上创建非 getter size 属性。

How can I rewrite my code to avoid this behavior?

不要将 Object.assign 用于包含附件属性作为源参数的对象。你可以写

function createApple(color) {
  return Object.defineProperties(createFruit(2), {
    color: {
      get() {
        return color;
      }
    }
  });
}