我检查了这个问题,因为我决定使用工厂函数而不是类。
我假设你有一个通用的工厂函数,比如Animal 或Mammal,它有一些特性(比如声音,就像一些建议的那样),你想继承它们并在另一个工厂函数中添加一些特定的特性。
让我们构建一个动物工厂函数:
const Animal = ({color = "green", numberOfLegs = 4} = {}) => {
const SetColor = (newColor) => {
color = newColor;
};
const GetColor= () => color;
const GetNumberOfLegs = () => numberOfLegs;
const MakeSound = () => console.log("Screetch");
return {
GetColor,
GetNumberOfLegs,
MakeSound
}
}
const newCreature = Animal({color: black, numberOfLegs: 3})
newCreature.MakeSound() // -> "Screetch"
让我们构建一个 Dog 工厂函数:
const Dog = ({name = "rex", color = "black", numberOfLegs = 4} = {}) => {
const MakeSound = () => console.log("Woof Woof");
const Roll = () => console.log(`${name} made a roll!`)
return {
MakeSound,
Roll
}
}
const sniffles = Dog({name: "sniffles", color: black, numberOfLegs: 4})
sniffles.MakeSound() // -> "Woof Woof"
sniffles.Roll() // -> "sniffles made a roll!"
如果我想继承我已经拥有的从Animal 获得的所有好东西,我该怎么办?
使用 ES6 Spread Syntax 可以帮助我们实现一种非常简洁的方式:
const Dog = ({name = "rex", color = "black", numberOfLegs = 4} = {}) => {
const anAnimal = Animal({color, numberOfLegs}); // used the Animal factory!
const MakeSound = () => console.log("Woof Woof");
const Roll = () => console.log(`${name} made a roll!`)
return {
...anAnimal, // And That's where magic happens!
MakeSound,
Roll
}
}
const sniffles = Dog({name: "sniffles", color: black, numberOfLegs: 4})
sniffles.GetNumberOfLegs() // -> 4
sniffles.MakeSound() // -> "Woof Woof"
sniffles.Roll() // -> "sniffles made a roll!"
那么到底发生了什么?
在Dog 工厂中,我们将Animal 工厂调用到anAnimal,因此anAnimal 现在是一个对象。
在Dog工厂返回的对象中,我们传播了anAnimal对象,然后添加了Dog的属性。
如果你给一个对象两个相同的具有不同值的键,它将采用后者:
const someObject = {a: 1, b: 2, a: 3};
someObject // -> {a: 3, b: 2}
因此,您不必担心Dog 是否使用了已经从Animal 提供的任何密钥,因为它们已被覆盖。