`
babysuperman
  • 浏览: 1790 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

前端面试题—— 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?

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics