• 不会JS中的OOP,你也太菜了吧!(第二篇)


    一、你必须知道的

    1> 原型及原型链在继承中起到了关键的作用。所以你一定要理解他们。
    2> 不会JS中的OOP,你也太菜了吧!(第一篇)

     

    二、继承的6种方法

    1> 原型链继承

    原型链继承是通过创建Super的实例,并将该实例赋值给Sub.prototype来实现的。

    实现的本质是:重写子类型的原型对象,代之以超类型的实例。

    function Super(){
        this.name = 'JChen___';
    }
    Super.prototype.getSuperName = function(){
        return this.name;
    }
    
    function Sub(){
        this.subname = 'JChen___son';
    }
    Sub.prototype = new Super(); //原型继承体现在这里
    Sub.prototype.getSubName = function(){
        return this.subname;
    }
    
    var instance = new Sub();

    注意:此时instance.constructor现在指向的是Super的,这是因为Sub.prototype指向了Super.prototype,而Super.prototype.constructor = Super。

    原型链的问题:类似于利用原型创建对象,原型共享的特性也是原型链继承的最大问题。

     

    2> 借用构造函数继承

    在解决原型中包含引用类型值所带来的问题的过程中,我们开始使用一种叫做借用构造函数的技术。

    这种技术的基本思想相当简单:在子类型构造函数的内部调用超类型构造函数

    这样一来,就会在新子类对象上执行超类函数中定义的所有对象初始化代码。结果,每个子类的实力都会有自己的超类中属性的副本了。

    function Super2(name){
        this.colors = ['red', 'blue'];
        this.name = name;
    }
    
    function Sub2(){
        Super2.call(this, 'JChen___2'); //借用构造函数技术体现在这里
        this.age = 29;
    }
    
    var instance1 = new Sub2();
    instance1.colors.push('black');
    var instance2 = new Sub2();
    instance2.colors.push('green');

    借助构造函数继承的问题:

    1): 方法都在构造函数中定义,无法复用。

    2): 在超类型的原型中的方法对子类是不可见的。

     

    3> 组合继承(原型+借用构造)

    组合继承指的是将原型链和借用构造函数的技术组合到一块,从而发挥二者之长的一种继承模式。

    组合继承的思路:使用原型链实现对方法和属性的继承,通过借用构造函数实现对实例属性的继承。

    function Super3(name){
        this.name = name;
        this.colors = ['red', 'blue'];
    }
    Super3.prototype.sayName = function(){
        return this.name;
    }
    
    function Sub3(name, age) {
        Super3.call(this, name);
        this.age = age;
    }
    Sub3.prototype = new Super3(); //解决借用构造函数技术的缺点
    Sub3.prototype.constructor = Sub3; //纠正原型继承改变了的构造函数
    Sub3.prototype.sayAge = function(){
        return this.age;
    }

    组合继承避免了原型链和借用构造函数的缺陷,融合了他们的优点,成为JavaScript中最常用的继承模式。

    组合继承的问题:两次调用超类构造函数。

     

    4> 原型式继承

    原型式继承的思路:借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型。

    function object(o){ //原型式继承的关键
        function F(){}
        F.prototype = o;
        return new F();
    }
    var person = {
        name: 'JChen___4',
        colors: ['blue']
    }
    var person1 = object(person);
    person1.name = 'JChen___4___2'
    person1.colors.push('red');
    var person2 = object(person);
    person2.name = 'JChen___4___3';
    person2.colors.push('green');

    原型式继承的问题:同原型链一样,他也有共享的劣势。

     

    5> 寄生式继承

    寄生式继承的思路:创建一个仅用于封装继承过程的函数,该函数内部以某种方式来增强对象,最后再返回该对象

    function createAnother(origin){ //寄生式继承的关键
        var clone = object(origin);
        clone.sayHi = function(){
            return 'Hi';
        };
        return clone;
    }
    var person = {
        name: 'JChen___4',
        colors: ['blue']
    }
    var person1 = createAnother(person);

    寄生式继承的问题:像构造函数一样,由于不能做到函数的复用而降低效率。

     

    6> 寄生组合式继承

    寄生组合式继承:通过借用构造函数来借用属性,通过原型链的混成形式来继承方法。

    其背后的思想是:不必为了指定子类型的原型而调用超类型的构造函数,我们需要的无非就是超类型的一个副本而已。

    function object(o){
        function F(){}
        F.prototype = o;
        return new F();
    }
    function inheritProto(subType, superType){ //避免第一调用构造函数的关键
        var proto = object(superType.prototype);
        proto.constructor = subType;
        subType.prototype = proto;
    }
    
    function Super6(name){
        this.name = name;
        this.colors = ['red', 'blue'];
    }
    Super6.prototype.sayName = function(){
        return this.name;
    }
    
    function Sub6(name, age){
        Super6.call(this, name);
        this.age = age;
    }
    
    inheritProto(Sub6, Super6);
    
    Sub6.prototype.sayAge = function(){
        return this.age;
    }
    
    var instance1 = new Sub6('JChen___6', '12');
    instance1.colors.push('black');

    开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式。

     

    三、总结

    这就是JavaScript中的6种继承方式,如果大家能够画出每个继承的原型链关系图,那么继承就是小菜一碟了。

  • 相关阅读:
    11.14 mii-tool:管理网络接口的状态
    11.15 dmidecode:查询系统硬件信息
    11.11 ntsysv:管理开机服务
    HDU 2476 String painter 刷字符串(区间DP)
    HDU 1085 Holding Bin-Laden Captive! 活捉本拉登(普通型母函数)
    母函数的应用
    HDU 1028 Ignatius and the Princess III伊格和公主III(AC代码)母函数
    HDU 1059 Dividing 分配(多重背包,母函数)
    HDU 2955 Robberies抢劫案(01背包,变形)
    HDU 1011 Starship Troopers星河战队(树形dp)
  • 原文地址:https://www.cnblogs.com/JChen666/p/3375894.html
Copyright © 2020-2023  润新知