前端面试题—— JavaScript模拟类式继承

前端面试题系列—— JavaScript模拟类式继承

 

类式继承的需求

 

SuperClass是父类,SubClass是子类。我们需要达到的效果是,子类继承父类公有的属性和方法,方法依然为子类公有,子类继承父类的实例属性和方法,属性为子类各个实例自己的。举个栗子:

 

    function SuperClass( name ) {
        this.name = name;
    }

    SuperClass.prototype.sayName = function () {
        alert ( this.name );
    }

    function SubClass() {}

    inheritClass( SubClass, SuperClass );// inheritClass 是将要实现的类式继承操作

    var sub1 = new SubClass( 'jack' );

    var sub2 = new SubClass( 'king' );

    alert( sub1.name == 'jack' );// 期待返回true

    alert( sub2.name == 'king' );//期待返回true
    
    sub1.sayName(); //期待 alert( 'jack' )

 

 

  inheritClass( SubClass, SuperClass )该如何实现呢,首先继承原型链:

 

 

    function SuperClass( name ) {
        this.name = name;
    }

    SuperClass.prototype.sayName = function () {
        return this.name;
    }

    function SubClass() {}

    SubClass.prototype = new SuperClass();// 形成原型链

    var sub1 = new SubClass( 'jack' );

    var sub2 = new SubClass( 'king' );

    alert( sub1.name == 'jack' );// 期待返回flase;
    alert( sub1.name ); //'jack'

    alert( sub2.name == 'king' );//期待返回true;

    sub1.sayName(); //alert(' jack' );

 

可见name并不是每个实例自己的,实际上是子类公有的,在SubClass.prototyp.name上得到的,那如何改进呢,继续往下看:

 

    function SuperClass( name ) {
        this.name = name;
    }

    SuperClass.prototype.sayName = function () {
        return this.name;
    }

    function SubClass() {
        SuperClass.apply( this, arguments );  
    }

    SubClass.prototype = new SuperClass();// 形成原型链

    var sub1 = new SubClass( 'jack' );

    var sub2 = new SubClass( 'king' );

    alert( sub1.name == 'jack' );// true;

    alert( sub2.name == 'king' );//true;

    sub1.sayName(); //alert(' jack' );

 

我们利用apply来实现了该功能,但是SuperClass.prototyp.name依然存在,如果属性比较多的话是很大的浪费。如何继续改进呢,问题出在SubClass.prototype = new SuperClass();这个语句上,我们需要这里仅仅执行公有的方法和属性继承的操作。我们可以借用构造函数来完成这个任务:

 

    function SuperClass( name ) {
        this.name = name;
    }

    SuperClass.prototype.sayName = function () {
        return this.name;
    }

    function SubClass() {
        SuperClass.apply(this, arguments);
    }

    function prototypeInherit( o ) {
        function F(){};
        F.prototype = o;
        return new F();
    }

    function inheritClass( SubClass, SuperClass ) {
        var prototype = prototypeInherit( SuperClass.prototype );
        prototype.constructor = SubClass;
        SubClass.prototype = prototype;
    }

    inheritClass( SubClass, SuperClass );// inheritClass 是将要实现的类式继承操作

    var sub1 = new SubClass( 'jack' );

    var sub2 = new SubClass( 'king' );

    alert( sub1.name == 'jack' );//true

    alert( sub2.name == 'king' );//true

    alert( sub1.sayName() );//'jack'

    alert( sub1.constructor.name );

 

分析下两个函数:inheritClass的核心是构造一个SubClass.prototype:prototypeInherit( o )利用了一个公的构造函数F使得实例的属性和方法不会传到子类的prototype上。inheritClass( SubClass, SuperClass )需要做的是将prototype的constructor修正为SubClass,之前为SuperClass。小作业:想想之前为什么是SuperClass?

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值