与传播对象的组成

Composition with spread objects

我看了一个关于组合的教程,它让你像这样组合对象:

const eater = (state) => ({
  eat(amount) {
    console.log(state.name + ' is eating');
    state.energy += amount;
  }
});

// using a factory
const Dog = (name, energy, breed) => {
  let dog = {
    name,
    energy,
    breed
  };
  return Object.assign(dog, eater(dog));
};

const leo = Dog('Leo', 10, 'Pug');
leo.eat(10); // Leo is eating
console.log(leo.energy); // 20

我想知道你是否可以做类似的事情,这样做是否有任何缺点:

const eater = {
  eat(amount) {
    console.log(this.name + ' is eating');
    this.energy += amount;
  }
};

const Dog = (name, energy, breed) => {
  let dog = {
    name,
    energy,
    breed,
    ...eater
  };
  return dog;
};

const leo = Dog('Leo', 10, 'Pug');
leo.eat(10); // Leo is eating
console.log(leo.energy); // 20

如您所见,我没有使用 Object.assign 创建对象并将其分配给对象,而是使用一个方法创建了另一个对象 eater,然后我将其传播 eater对象并将其添加到正在工厂内创建的 dog 对象。

那么,这样做有什么不妥吗?

谢谢!

这两种方法非常相似。两者都是可行的好方法。

区别如下:

  • 第一种方法:eater是工厂函数

    • 为每个 dog
    • 创建新的 eater 对象和 eat 函数
    • eat方法绑定:

      let leoEat = leo.eat;
      leoEat(10); //works
      
  • 第二种做法:eater是对象

    • 重用eater对象和eat函数
    • eat 未绑定:

      const leo = Dog('Leo', 10, 'Pug');
      const animal = {name: 'Animal', energy: 0};
      leo.eat.call(animal, 30); // Animal is eating
      console.log(animal.energy); // 30
      console.log(leo.energy); // 10
      
  • 第三种方法(是的,有!):EaterDog是类

    • 重用eat函数
    • eat 未绑定
    • 利用原型
    • 不支持多重继承

class Eater {
  eat(amount) {
    console.log(this.name + ' is eating');
    this.energy += amount;
  }
};

class Dog extends Eater{
  constructor (name, energy, breed) {
    super();
    Object.assign(this, {
      name,
      energy,
      breed
    })
  }
};

const leo = new Dog('Leo', 10, 'Pug');
leo.eat(10); // Leo is eating
console.log(leo.energy); // 20
console.log(leo instanceof Dog) //true
console.log(leo instanceof Eater) //true