资讯专栏INFORMATION COLUMN

JS-ES5模拟super与多级继承(一)

李世赞 / 3474人阅读

摘要:参考文章多层继承方法本系列文章对实现多级继承做一个学习和探究第三篇给出最终的模拟代码及测试用例简单的父子继承父类子类原型链继承这里我用了关键字表示了继承的父类方法可以将其附加到子类实例对象上用起来会方便一点但是比较致命的一点是这种方式不适

参考文章

js多层继承 super方法

本系列文章对js es5实现多级继承做一个学习和探究, 第三篇给出最终的模拟代码及测试用例.

简单的父-子继承
// 父类A
function A(a){
    this.a = a;
}

A.prototype.sayA = function(){
    console.log(this.a);
};

// 子类B
function B(a, b){
    this._super.call(this, a);
    this.b = b;
}

// 原型链继承
Object.assign(B.prototype, A.prototype, {
    constructor: B, 
    _super: A
});

B.prototype.sayB = function(){
    console.log(this.b);
};

var b = new B(1, 2);
b.sayA();   // 1
b.sayB();   // 2

这里我用了_super关键字表示了继承的父类, Object.assign()方法可以将其附加到子类实例对象上, 用起来会方便一点.

但是, 比较致命的一点是, 这种方式不适用于多级继承, 我所定义的_super反而成了限制.

// 父类A
function A(a){
    this.a = a;
}

A.prototype.sayA = function(){
    console.log(this.a);
};

// 子类B
function B(a, b){
    this._super.call(this, a);
    this.b = b;
}

// 原型链继承
Object.assign(B.prototype, A.prototype, {
    constructor: B, 
    _super: A
});

B.prototype.sayB = function(){
    console.log(this.b);
};

// 子类C
function C(a, b, c){
    this._super.call(this, a, b);
    this.c = c;
}

// 原型链继承
Object.assign(C.prototype, B.prototype, {
    constructor: C, 
    _super: B
});

C.prototype.sayC = function(){
    console.log(this.c);
};

var c = new C(1, 2, 3);
c.sayA();
c.sayB();
c.sayC();

上面的代码看起来似乎没什么错误, 但是执行时, 会栈溢出, 在B类函数体的this._super.call(this, a);这一行.

VM4484:10 Uncaught RangeError: Maximum call stack size exceeded
    at C.B [as _super] (:10:11)
    at C.B [as _super] (:11:17)

原因在于, c在实例化时构造函数调用父类B的构造函数, 但用的是call方法, B类构造函数在执行时this的值为c的实例, 而this._super的值又是B, 于是就在B的构造函数里一直循环.

要解决这个问题, _super变量就不能绑定在this上, 但是好像也没有好的方法绑定在子类本身, 除非在子类中用父类的类名显示调用父类的同名方法. 但这样耦合性太强, 稍不注意就会出错(尤其是代码复制时).

参考文章1中有错误, 不存在__super__属性, 但它给了我一个启示, super不一定非得是变量, 也可以是一个函数, 由函数的执行结果作为父类对象也是一种方法.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92835.html

相关文章

  • JS-ES5模拟super多级继承(二)

    摘要:参考文章官网是一个的编译器它可以将的代码转换成等价的我们看看它是怎么模拟关键字的与上面等价的语句如下貌似不支持多重继承啊覆写子类的对象设置隐式原型感觉这样很怪因为这样意为着子类将成为父类的实例对象呃类似的概念但我不觉得父子类关系与类和实 参考文章 Babel官网 babel是一个es6->es5的编译器, 它可以将es6的代码转换成等价的es5. 我们看看它是怎么模拟super关键字的...

    yearsj 评论0 收藏0
  • JS-ES5模拟super多级继承(三)

    摘要:参考文章多层继承方法参考文章中提供了一个思路不一定要是一个变量也可以是一个函数只要它能返回我们期望的父级对象就可以了下面是我对它给出的源码的一些修改和注释另外有个测试示例要想拥有方法必须继承类注意方法中不要再在时为子类添加指向父类本身的属 参考文章 js多层继承 super方法 参考文章1中提供了一个思路, _super不一定要是一个变量, 也可以是一个函数, 只要它能返回我们期望的父...

    VioletJack 评论0 收藏0
  • javascript之模拟继承

    摘要:欢迎关注我的博客正文让我来构造函数其实,模拟一个类的方式非常的简单构造函数。我们先来看一个例子这里通过构造函数模拟出来的类,其实和其他语言的类行为上是基本一致的,唯一的区别就是它不具备私有方法。 前言 ES6时代的来临,使得类继承变得如此的圆滑。但是,你有思考过ES6的类继承模式吗?如何去实现它呢? 类继承对于JavaScript来说,实现方式与Java等类语言大不相同。熟悉JavaS...

    Jochen 评论0 收藏0
  • 超级白中白的学习进程(2):继承(Extends)

    摘要:父类中的访问权限一定要小于或者等于子类访问权限的个关键字访问权限大小,其中为默认值,不用写。下面是一个典型的代码父类代码子类代码测试类代码输出结果在子类那里已经表明。 继承(Extends)1、前言还是先说一下博主本人的一些基本情况吧。本人去年刚刚毕业,专业是电气工程及其自动化,就是在大学期间完全没有接触过JAVA,也就稍稍了解了一下C语言。后来找了现在的工作也是和编程没有任何关系,是...

    pkwenda 评论0 收藏0
  • JavaScript常用的继承方式

    摘要:常用继承方式主要分为种原型链继承构造函数继承组合继承原型式继承寄生式继承寄生组合继承以及继承多个对象。所以说,构造函数基础只能继承父类的实例属性和方法,不能继承原型链上的属性和方法。 JavaScript常用继承方式主要分为(7种):原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合继承以及继承多个对象。 1:原型链继承(核心:将父类的实例作为子类的原型) 基本概念:...

    zhangfaliang 评论0 收藏0

发表评论

0条评论

李世赞

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<