从 Parent 创建 Child Class(Javascript 中的 ES6 Classes)
Create Child Class From Parent (ES6 Classes in Javascript)
我想做什么
我正在尝试创建一个 child(子)class,方法是使用 child 类型作为参数启动 parent class,并且我想知道如何做到这一点。
例如,假设我有以下起始代码:
class Animal{
constructor(settings){
//parent value
this.name = settings.name;
}
//parent function
sayName(){
console.log(`My name is ${this.name}.`);
}
}
class Frog extends Animal{
constructor(settings){
super(settings);
//child-specific value
this.isTreeFrog = settings.isTreeFrog;
}
//child function
livesInTheForest(){
return this.isTreeFrog;
}
}
class Rabbit extends Animal{ [...] }
class Whale extends Animal{ [...] }
我希望能够写作:
let barry = new Animal({
animalType: "frog",
name: "Barry",
isTreeFrog: false
})
(而不是 let barry = new Frog({name: "Barry", isTreeFrog: false})
)
并让 barry
成为一只青蛙,这意味着我可以这样写:
barry.sayName() //should print 'My name is Barry'
console.log(barry.livesInTheForest()) //should print 'false'
我试过的
我已经尝试了两种不同的方法来实现这一点,但都有些老套,并没有完全达到我想要的效果。
第一个涉及在存储 child 的 Animal class 中有一个值。例如,在 Animal
的构造函数中我可能有这样的东西:
if(settings.animalType === "frog"){
this.animal = new Frog(settings);
}else [...] //other animal types
这有两个主要问题:
- 我必须像这样调用 child 函数:
barry.animal.livesInTheForest()
,这会造成不一致,因为可以在没有 .animal
.[=59= 的情况下调用 parent 函数]
- child classes (e.g.
Frog
) 不能再是 child classes ,否则我会得到太多的递归它一直试图用 super() 调用自己。
我也想到了第二种方法,效果是这样的:
在parent (Animal
)构造函数中:
//make sure this isn't being called from the child class
if(settings.animalType !== null){
if(settings.animalType === "frog"){
//set settings.animal null to avoid too much recursion
//this means that I can't set this.animalType though, so I can't access barry.animalType
settings.animalType = null;
//Is this something I can do?!
this = new Frog(settings);
} else [...] //other animal types
}
这可行(我认为),但我现在无法将 this.animalType
设置为 settings.animalType
,这意味着我无法写入 barry.animalType
并获得 frog
。
另外,这对我来说真的很老套,我忍不住想一定有更好的方法来做到这一点。
class Animal {
static create (settings) {
return new this.subClasses[settings.type](settings)
}
}
class Rabbit extends Animal {}
class Frog extends Animal {}
class Whale extends Animal {}
Animal.subClasses = { frog: Frog, rabbit: Rabbit, whale: Whale }
const animals = ['frog', 'rabbit', 'whale'].map((type) => Animal.create({ type }))
console.log({ animals })
我想做什么
我正在尝试创建一个 child(子)class,方法是使用 child 类型作为参数启动 parent class,并且我想知道如何做到这一点。
例如,假设我有以下起始代码:
class Animal{
constructor(settings){
//parent value
this.name = settings.name;
}
//parent function
sayName(){
console.log(`My name is ${this.name}.`);
}
}
class Frog extends Animal{
constructor(settings){
super(settings);
//child-specific value
this.isTreeFrog = settings.isTreeFrog;
}
//child function
livesInTheForest(){
return this.isTreeFrog;
}
}
class Rabbit extends Animal{ [...] }
class Whale extends Animal{ [...] }
我希望能够写作:
let barry = new Animal({
animalType: "frog",
name: "Barry",
isTreeFrog: false
})
(而不是 let barry = new Frog({name: "Barry", isTreeFrog: false})
)
并让 barry
成为一只青蛙,这意味着我可以这样写:
barry.sayName() //should print 'My name is Barry'
console.log(barry.livesInTheForest()) //should print 'false'
我试过的
我已经尝试了两种不同的方法来实现这一点,但都有些老套,并没有完全达到我想要的效果。
第一个涉及在存储 child 的 Animal class 中有一个值。例如,在 Animal
的构造函数中我可能有这样的东西:
if(settings.animalType === "frog"){
this.animal = new Frog(settings);
}else [...] //other animal types
这有两个主要问题:
- 我必须像这样调用 child 函数:
barry.animal.livesInTheForest()
,这会造成不一致,因为可以在没有.animal
.[=59= 的情况下调用 parent 函数] - child classes (e.g.
Frog
) 不能再是 child classes ,否则我会得到太多的递归它一直试图用 super() 调用自己。
我也想到了第二种方法,效果是这样的:
在parent (Animal
)构造函数中:
//make sure this isn't being called from the child class
if(settings.animalType !== null){
if(settings.animalType === "frog"){
//set settings.animal null to avoid too much recursion
//this means that I can't set this.animalType though, so I can't access barry.animalType
settings.animalType = null;
//Is this something I can do?!
this = new Frog(settings);
} else [...] //other animal types
}
这可行(我认为),但我现在无法将 this.animalType
设置为 settings.animalType
,这意味着我无法写入 barry.animalType
并获得 frog
。
另外,这对我来说真的很老套,我忍不住想一定有更好的方法来做到这一点。
class Animal {
static create (settings) {
return new this.subClasses[settings.type](settings)
}
}
class Rabbit extends Animal {}
class Frog extends Animal {}
class Whale extends Animal {}
Animal.subClasses = { frog: Frog, rabbit: Rabbit, whale: Whale }
const animals = ['frog', 'rabbit', 'whale'].map((type) => Animal.create({ type }))
console.log({ animals })