Javascript实现多类继承
好像在Javascript中多继承出现的场景并不多,这是因为在es6中并没有显式的支持多继承,不过,如果你认为它不能做到多继承就错了。
比如有类A、B、C、D,我希望类A去继承B、C、D,那么,可以让B去继承C,C继承D,最后让A继承B,就实现了多继承的效果。
在es6中,通过extends
关键字去实现继承,如下示例。
class B extends C {}
class C extends D {}
但是,这样一层一层的去写也太麻烦了,那么我们需要了解另一个原理。
extends
关键字之后除了放一个类或构造函数,还可以是一个Javascript表达式,任何一个可以解析为类或构造函数的表达式都是有效的,它会在求值类定义时被求值。
我们把extends
之后的class改为一个表达式如下。
class Parent {}
function getParentClass() {
console.log('get parent class')
return Parent;
}
class Child extends getParentClass() {}
所以上述代码片段在控制台打印了get parent class
。
基于这个特性,上面B、C、D三个类可以通过混入类的方式来实现效果。我们实现一个混入类的函数,该函数接收一个类作为参数,在函数内部去继承这个传入的类。
function Parent() {
console.log('parent')
}
const ParentMixin = (SuperClass) => class extends SuperClass {
parentLog() {
console.log('parent log')
}
}
const ChildMixin = (SuperClass) => class extends SuperClass {
childLog() {
console.log('child log')
}
}
const SubChildMixin = (SuperClass) => class extends SuperClass {
subChildLog() {
console.log('subchild log')
}
}
class Base extends SubChildMixin(ChildMixin(ParentMixin(Parent))) {}
const instance = new Base(); // parent
instance.subChildLog() // subchild log
instance.childLog() // child log
instance.parentLog() // parent log
这样写的话代码层层套娃不够简单优雅,实现一个辅助pipe
函数,将函数的嵌套展开。
const pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x);
class Base extends pipe(SubChildMixin, ChildMixin, ParentMixin)(Parent) {}
总结
js多继承的使用场景并不是很多,甚至很多地方已经不建议使用多继承的方式,但是并不妨碍我们了解它的实现原理。
本文完。😊
如果您觉得本文对您有用,欢迎捐赠或留言~
- 本博客所有文章除特别声明外,均可转载和分享,转载请注明出处!
- 本文地址:https://www.leevii.com/?p=2884