zoukankan      html  css  js  c++  java
  • js继承

    6种继承方式:

    1.原型链继承
    2.借用构造函数(经典继承)
    3.组合继承
    4.原型式继承
    5.寄生式继承
    6.寄生组合式继承

    1.原型链:

    缺点:所有实例会共享属性

         新实例无法向父类构造函数传参

            function FirstProto() {
                this.name = 'xiaoming';
                this.colors = ['red', 'yellow'];
            };
    
            function SecProto() {}
            SecProto.prototype = new FirstProto();
            var instance1 = new SecProto();
            instance1.colors.push('black');
            console.log(instance1.name, instance1.colors); //xiaoming ["red", "yellow", "black"]
    
            var instance2 = new SecProto();
            console.log(instance2.name, instance2.colors); //xiaoming ["red", "yellow", "black"]

    2.借用构造函数     :各自继承,不会共享

    function FirstProto(){
    this.colors=['red','yellow'];
    };
    function SecProto(){
       FirstProto.call(this);
    }
    var instance1=new SecProto();
    instance1.colors.push('black');
    console.log(instance1.colors);//["red", "yellow", "black"]
    
    var instance2=new SecProto();
    console.log(instance2.colors);//["red", "yellow"]

    还可以传递参数

    function FirstProto(col){
    this.colors=['red','yellow',col];
    };
    function SecProto(){
       FirstProto.call(this,'blue');
    }
    var instance1=new SecProto();
    instance1.colors.push('black');
    console.log(instance1.colors);// ["red", "yellow", "blue", "black"]
    
    var instance2=new SecProto();
    console.log(instance2.colors);// ["red", "yellow", "blue"]

    存在的问题:方法都在构造函数中定义好了,不存在函数的复用

    即:1.只是子类的实例,不是父类的实例
    2.方法都在构造函数中定义,每次创建实例都会创建一遍方法

    3.组合继承
    思路是:使用原型链实现对原型方法的继承,而通过借用构造函数来实现对实例属性的继承。
    function FirstProto(name){
        this.colors=['red','yellow'];
        this.name=name;
    };
    FirstProto.prototype.sayname=function(){
      console.log(this.name);
     }
    function SecProto(name,age){
       //继承属性
       FirstProto.call(this,name);         //第二次调用父类
       this.age=age;
    }
    SecProto.prototype=new FirstProto();    //第一次调用父类 
    SecProto.prototype.constructor=SecProto;
    SecProto.prototype.sayage=function(){
      console.log(this.age);
     }
    var instance1=new SecProto('Sun menghua',24);
    instance1.colors.push('black');
    instance1.sayname();//Sun menghua
    instance1.sayage();//24
    console.log(instance1.colors);//["red", "yellow", "black"]
    
    var instance2=new SecProto('Qi Haiyang',25);
    instance2.sayname();// Qi Haiyang
    instance2.sayage();//25
    console.log(instance2.colors);//["red", "yellow"]
    优点:融合原型链继承和构造函数的优点,是JavaScript中最常用的继承模式
    缺点:调用了两次父类构造函数
    (组合继承最大的问题是无论什么情况下,都会调用两次超类型构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数内部)

    4.原型式继承

    基于已有的对象创建新对象

    ①obj()浅复制

    对象的属性会共享

    function obj(o){
     function F(){}
     F.prototype=o;
     return new F();
    }
    var person={
    name:"zhangsan",
    age:18,
    friends:['Lisi','wangwu','zhaoliu']
    };
     var thePerson=obj(person);
    thePerson. name='Sunmenghua';
    thePerson.friends.push('liulaogen');
    console.log(thePerson.name); //Sunmenghua
    console.log(thePerson.friends);
    //["Lisi", "wangwu", "zhaoliu", "liulaogen"]
    
     var theOtherPerson=obj(person);
    theOtherPerson. name='Qi Haiyang';
    theOtherPerson.friends.push('Da liu');
    console.log(theOtherPerson.name);
    //Qi Haiyang
    console.log(theOtherPerson.friends);
    // ["Lisi", "wangwu", "zhaoliu", "liulaogen", "Da liu"]
    
    console.log(thePerson.name);
    //Sunmenghua
    console.log(thePerson.friends);
    // ["Lisi", "wangwu", "zhaoliu", "liulaogen", "Da liu"]
    
    console.log(person.name);
    //zhangsan

    缺点: 包含引用类型的属性值始终都会共享相应的值, 这点跟原型链继承一样

    注意: 这里修改了thePerson.name的值,theOtherPerson.name的值并未改变,并不是因为thePerson和theOtherPerson有独立的name值,而是thePerson.name="Sunmenghua'是给thePerson添加了name值,并非修改了原型上的name值。

    因为我们找对象上的属性时,总是先找实例上对象,没有找到的话再去原型对象上的属性。实例对象和原型对象上如果有同名属性,总是先取实例对象上的值
    还可采用Object.create()方法,具体见https://i.cnblogs.com/posts/edit;postId=8880863

    5.寄生式继承

    创建一个仅用于封装继承过程的函数,该函数在内部以某种形式来做增强对象,最后返回对象。
    可以理解为在原型式继承的基础上新增一些函数或属性。

            function obj(o) {
                function F() {}
                F.prototype = o;
                return new F();
            }
    
            function createPerson(orig) {
                var thePerson = obj(orig);
                thePerson.sayHi = function() {
                    console.log('hi');
                };
                thePerson.sex = 'female';
                return thePerson;
            }
    
            var person = {
                name: "zhangsan",
                age: 18,
                friends: ['Lisi', 'wangwu', 'zhaoliu']
            };
            var newPerson = createPerson(person);
            newPerson.sayHi(); //hi
            console.log(newPerson.friends); //["Lisi", "wangwu", "zhaoliu"]
            console.log(newPerson.sex); //female

    函数不能复用,降低效率,但新对象不仅具有person的属性和方法,还有自己的方法。

    6.寄生组合式继承

            // 寄生组合式继承
            function Parent(name) {
                this.name = name;
                this.colors = ['blue', 'green'];
            }
            Parent.prototype.sayName = function() {
                console.log(this.name);
            }
    
            function Child(name, age) {
                Parent.call(this, name);
                this.age = age;
            }
    
            function CreateObj(o) {
                function F() {};
                F.prototype = o;
                return new F();
            }
    
            // Child.prototype = new Parent(); // 这里换成下面
            function prototype(child, parent) {
                var prototype = CreateObj(parent.prototype);
                prototype.constructor = child;
                child.prototype = prototype;
            }
            prototype(Child, Parent);
    
            var child1 = new Child('xiaopao', 18);
            child1.colors.push('red');
            console.log(child1);  //name: "xiaopao", colors: ["blue", "green", "red"], age: 18
            var child2 = new Child('xiao', 19); 
            console.log(child2); //name: "xiao", colors: ["blue", "green"], age: 19

    只调用了一次Parent构造函数,并且因此在避免了Parent.prototype上面创建不必要的多余的属性。普遍认为寄生组合式继承是引用类型最理想的继承方式

  • 相关阅读:
    jq 比较五获取结构树的位置 eq() 或者parent
    jq 笔记四 end的用法
    jq 笔记三 find的用法
    jq 笔记二filter()用法
    jq 笔记一 选择器中的逗号
    Linux 笔记五 搜索命令的命令
    linux 笔记四 文件搜索(locate)
    使用ansible时显示Failed to connect to the host via ssh
    linux音频解码软件ffmpeg的安装
    centos服务器jenkins安装配置
  • 原文地址:https://www.cnblogs.com/sunmarvell/p/8881608.html
Copyright © 2011-2022 走看看