我正在阅读JavaScript中不同的对象创建方法,而不是使用new
和ES6类。一种方法是使用工厂方法/工厂类模式(取自https://medium.com/humans-create-software/factory-functions-in-javascript-video-d38e49802555):
const dog = () => {
const sound = 'woof'
return {
talk: () => console.log(sound)
}
}
const sniffles = dog()
sniffles.talk() // Outputs: "woof"
我如何实现像Animal
这样的类,或者我的狗功能可以继承的另一种工厂功能"继承"从?我是否会将动物对象传递给dog函数并将对象的原型设置为返回传递的动物对象?
答案 0 :(得分:5)
您可以使用const animal = () => ({
talk: function() {
console.log(this.sound);
}
});
const dog = () => Object.create(animal(), {
sound: {
value: "woof"
}
});
// or...
const dog2 = () => {
var someDog = Object.create(animal());
someDog.sound = "woof";
return someDog;
};
var someDog = dog();
someDog.talk();
var someDog2 = dog2();
someDog2.talk();
:
Object.create
顺便说一下,我的意见是你应该使用ES2015 +类/继承并将自定义工厂和
class Animal {
talk() {
return console.log(this.sound);
}
}
class Dog extends Animal {
constructor() {
super();
this.sound = "woof";
}
}
var dog = new Dog();
dog.talk();
用于你真正需要它们的极端情况:
d = {'a' :
{ 'E' : (x,y) , # EndPoint
'S' : (x,y) } # StartPoint
}
答案 1 :(得分:2)
@nils是对的,不清楚你想继承什么/为什么,所以我只是猜测,但也许这就是你的意思:)。
const animal = (sound) => {
return {
talk: () => console.log(sound)
}
}
const dog = () => animal('woof')
const sniffles = dog()
sniffles.talk() // Outputs: "woof"
答案 2 :(得分:1)
除了这些其他答案之外,我建议您查看这本关于Javascript设计模式的优秀书籍Learning JavaScript Design Patterns。
特别要看一下factories的章节。
要在工厂模式中实现继承,其原始工厂类接受配置对象。更具体的工厂只是通过传入对象来扩展原始工厂类。
答案 3 :(得分:0)
我检查了此问题,因为我决定使用工厂函数而不是类。
我假设您具有一般的工厂功能,例如Animal
或Mammal
,它具有某些特性(例如声音,如建议的一样),并且您想要继承它们并在另一个工厂中添加一些特定的特性功能。
让我们建立一个Animal工厂功能:
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
工厂中,我们在{em> anAnimal 中调用了Animal
工厂,因此anAnimal现在是一个对象。
在Dog
工厂返回的对象中,我们传播anAnimal对象,然后添加了Dog
的属性。
如果为Object提供两个具有不同值的相同键,则将采用后者:
const someObject = {a: 1, b: 2, a: 3};
someObject // -> {a: 3, b: 2}
因此,Dog
是否使用Animal
中已经提供的任何键,都不必担心,因为它们已被覆盖。