• Javascript高级程序设计——面向对象之实现继承


    原型链:

      构造函数中都有一个prototype属性指针,这个指针指向原型对象,而创建的实例也有指向这个原型对象的指针__proto__。当实例查找方法时先在实例上找,找不到再通过__proto__到原型对象上查找。如果原型对象是另一个类型的实例,那么原型对象包含一个指向另一个原型对象的指针、另一个原型对象中也包含指向另一个构造函数的指针。

    原型连继承
    function
    superValue(){ this.superValue = "superValue"; } superValue.prototype.getSuperValue(){ return this.superValue; } function subValue(){ this.subValue = "subValue"; } subValue.prototype = new superValue(); //原型被superValue实例替换,实现继承superValue的属性和方法。没有了constructor subValue.prototype.getSubValue = function(){ return this.subValue; } var instance = new subValue(); instance instanceof Object //true,所以的引用类型都继承Object,也是通过原型链继承的。 instance instanceof superValue; //true instance instanceof subValue; //true //只要原型链出现过的构造函数,结果就返回true。

    所以的函数类型都是Object的实例,所以instance instanceof Object  返回true

    问题:

    通过原型继承时会共享所有引用类型的属性

    不能向超类的构造函数传递参数。

      

    借用构造函数:

    又名伪造对象。在子类型的函数的内部调用超类的构造函数

    function superValue(){
        this.colors = ["yellow", "green", "red"];
    }
    
    
    function subValue(){
        //继承了superValue
        superValue.call(this);
    }
    
    var instance1 = new subValue();
    instance1.color.push("new");
    instance1.color         //["yellow", "green", "red", "new"]
    
    var instance1 = new subValue();
    instance1.color         //["yellow", "green", "red"] 不共享属性

    问题:构造函数的内部调用父类的构造函数,无法实现函数复用

      

    组合继承:

    利用原型链实现方法的继承,达到函数复用。

    利用构造函数实现实例的属性继承,避免了引用实例的共享问题

    function superValue(name){
        this.name = name;
        this.color = ["red", "green"];
    }
    
    superValue.prototype.sayName = function(){
        alert(this.name);
    }
    
    function subValue(age, name){
        superValue.call(this, name);      //对构造函数的属性的继承
        this.age = age;
    }
    
    //实现继承superValue
    subValue.prototype = new superValue(); 
    //恢复被覆盖的构造函数
    subValue.prototype.constructor = subValue;
    //定义自己的方法
    subValue.prototype.sayAge = function(){
        alert(this.age);
    }
    
    var instance = new subValue(24, "yang");
    instance.color.push("black");
    instance.color                       //["red", "green", "black"];
    instance.sayName()                   //yang 继承来的方法
    instance.sayAge()                    //24 自己的方法
    
    var instance2 = new subValue(25, "he");
    instance.color                        //["red", "green"]不共享引用类型。
    instance.sayName()                   //he 继承来的方法
    instance.sayAge()                    //25 自己的方法

    问题:继承时调用了两次supeValue()一次函数内部,一次实例化原型对象,子类型屏蔽了原型对象上的属性,可以通过寄生组合类型继承解决。

      原型继承:

    function object(obj){
        funciton F();            //声明一个临时的构造函数
        F.prototype = obj;        //实现原型继承
        return new F();            //返回构造函数实例。
    }
    
    //整个过程是一个浅复制

      寄生式继承:

      与寄生构造函数和工厂模式类似,即创建一个仅用于封装过程的函数,在内部增强对象。

    function object(obj){
        var clone = object(obj);
        clone.sayName = function(){
            alert(haha"");
        }
        
        return clone;
    }
    //函数内部增强对象

      寄生组合类型继承:

      解决组合继承中两次调用superValue()函数。这两次调用superValue()会在原型对象和新对象上创建属性。

    function superValue(name){
        this.name = name;
        this.color = ["red", "green"];
    }
    
    superValue.prototype.sayName = function(){
        alert(this.name);
    }
    
    function subValue(age, name){
        superValue.call(this, name);      //调用父类构造函数创建属性name和color。屏蔽原型上的属性name和color 
        this.age = age;
    }
    
    //实现继承superValue,在原型上创建属性name和color
    subValue.prototype = new superValue(); 
    
    subValue.prototype.constructor = subValue;
    subValue.prototype.sayAge = function(){
        alert(this.age);
    }

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

    方法:不必为了指定子类型的原型而调用超类的构造函数。通过寄生式继承超类原型,指定给子类原型

    function inheritPrototype(subType, superType){
        var prototype = object(super.prototype);    //创建对象
        prototype.constructor = subType;         //增强对象
        subType.prototype = prototype;            //指定对象
    }

    寄生组合继承代码

    function superValue(name){
        this.name = name;
        this.color = ["red", "green"];
    }
    
    superValue.prototype.sayName = function(){
        alert(this.name);
    }
    
    function subValue(age, name){
        superValue.call(this, name);    //实现属性的继承
        this.age = age;
    }
    //原型链方法继承
    inheritPrototype(subType, superType);
    
    subValue.prototype.sayAge = function(){
        alert(this.age);
    }
  • 相关阅读:
    基于阿里云GPU云服务器的AIACC助力UC搜索业务性能提效380%,每年节省数千万成本
    如何在 ACK 中使用 MSE Ingress
    面向对象分析与设计的底层逻辑
    当 AI 邂逅绘画艺术,能迸发出怎样的火花?
    是什么让一段20行代码的性能提升了10倍
    我,PolarDB云原生数据库,5年来实现这些重磅技术创新
    一图看懂天河文链如何实现云原生架构升级
    首次全面解析云原生成熟度模型:解决企业「诊断难、规划难、选型难」问题
    C++快速初始化vector
    Grid布局指定列数时,行高自适应为元素高度
  • 原文地址:https://www.cnblogs.com/yangxunwu1992/p/4780545.html
Copyright © 2020-2023  润新知