• ES5继承


    1 构造函数继承

    function Person() { 
      this.name = '升高';
      this.arr = [1,2,3,4];
    }
    
    Person.prototype.sayName = function () { 
      console.log('Person.prototype',this.name);
    }
    
    function Child() { 
      Person.call(this);
      this.age = 1;
    }
    
    let child1 = new Child();
    let child2 = new Child();
    
    console.log('child1.name', child1.name);
    child1.sayName();
    // 缺点 无法继承父类构造函数的原型对象的属性和方法
    

    2 原型链继承

    function Person() { 
      this.name = '升高';
      this.arr = [1,2,3,4];
    }
    
    Person.prototype.sayName = function () { 
      console.log('Person.prototype',this.name);
    }
    
    function Child() { 
      this.age = 1;
    }
    
    Child.prototype = new Person();
    
    let child1 = new Child();
    let child2 = new Child();
    
    child1.name = '升高啊'; 
    console.log('child1.name', child1.name); // Child的prototype属性中获取
    console.log('child2.name', child2.name); // //实例中的属性会覆盖掉原型中的属性。不会改变原型中的属性。
    
    child1.arr.push(5);
    console.log('child1.arr', child1.arr); //arr指针指向堆中的一处内存。通过指针修改内存,所有实例访问arr时,arr都会被取到更新后的值。
    console.log('child2.arr', child2.arr); 
    child1.sayName();
    

    3 组合继承

    function Person() { 
      this.name = '升高';
      this.arr = [1,2,3,4];
    }
    
    Person.prototype.sayName = function () { 
      console.log('Person.prototype',this.name);
    }
    
    /**
     *继承父类的实例属性
     */
    function Child() { 
      Person.call(this);
      this.age = 1;
    }
    
    Child.prototype = new Person(); // 内部__proto__可访问到Person.prototype
    
    let child1 = new Child();
    let child2 = new Child();
    
    console.log('child1.name', child1.name); //现在child实例中去找。找到了,不去找原型
    child1.sayName(); //实例属性找不到,从prototype对象中找。找不到通过__proto__去原型中去找
    
    console.log(Object.getPrototypeOf(child1).constructor); //Person
    /**  缺点
     * 1 父类构造函数调用了两次
     * 2 子类的构造函数属性显示不正确 
    */
    

    4 组合继承优化

    function Person() {
      this.name = '升高';
      this.arr = [1, 2, 3, 4];
    }
    
    Person.prototype.sayName = function () {
      console.log('Person.prototype', this.name);
    }
    
    function Child() {
      Person.call(this);
      this.age = 1;
    }
    
    //Object.create默认创建一个{},并将空对象的__proto__设置为所传的第一个参数。第二个参数为设置其数据属性或者访问器属性
    //Child.prototype = Object.create(Person.prototype);
    Child.prototype = Person.prototype;
    Child.prototype.constructor = Child; //添加构造器属性
    
    let child1 = new Child();
    let child2 = new Child();
    
    child1.sayName();
    
    child1.arr.push(5);
    console.log('child1.arr', child1.arr);
    console.log('child2.arr', child2.arr);
    
    console.log(child1.constructor, Object.getPrototypeOf(child1).constructor);
    
    /** 优点
     * 1 解决了调用两次父类实例的问题
     * 2 解决了不能判断实例的构造函数是子类还是父类的问题
     */
    
    /** es5和es6继承的区别
     * 1 es5先构建子类的this,然后将父类属性添加到当前this当中。
     * 2 es6先构建父类的this,然后将子类的属性添加到当前this当中。
     * 
     * */
    
  • 相关阅读:
    重构与模式:改善代码三部曲中的第三部
    将博客搬至CSDN
    管理之道(二十二)
    管理之道(二十一)
    管理之道(二十)
    管理之道(十九)
    管理之道(十八)
    管理之道(十七)
    管理之道(十六)
    管理之道(十五)
  • 原文地址:https://www.cnblogs.com/shenggao/p/12381337.html
Copyright © 2020-2023  润新知