zoukankan      html  css  js  c++  java
  • JavaScript各种继承方式(二):借用构造函数继承(constructor stealing)

    一 原理

    在子类的构造函数中,通过call ( ) 或 apply ( ) 的形式,调用父类的构造函数来实现继承。

    function Fruit(name){
        this.name = name;
        this.eat = function(){
            console.log('eat');
        };
    }
    
    Fruit.prototype.desc = function(){
        console.log('desc');
    };
    
    function Mango(name,level){
        Fruit.call(this,name);
        this.level = level;
    }
    
    let mango1 = new Mango('泰国芒果','优');
    console.log(mango1);
    let mango2 = new Mango('海南芒果','良');
    console.log(mango2);
    
    // 都是子类实例的私有属性,没有从父类共享
    console.log(mango1.name == mango2.name); // false
    
    // 没有继承父类的原型对象中的方法
    console.log(mango1.desc); // undefined
    
    // 不支持instanceof
    console.log(mango1 instanceof Fruit); // false
    console.log(mango2 instanceof Fruit); // false
    
    // 无法复用父类的实例方法
    console.log(mango1.eat === mango2.eat); // false

    二 优点

    1 解决了原型链继承方式中,子类的对象会共享父类构造函数的原型对象的问题。

    2 创建子类的对象时,可以向父类构造函数中传递参数。

    3 可以实现多继承(call/apply多个父类的构造函数)

    三 缺点

    1 创建的实例并不是父类的实例,只是子类的实例。

    2 没有拼接原型链,不能使用instanceof。因为子类的实例只继承了父类的实例属性/方法,没有继承父类的构造函数的原型对象中的属性/方法。

    3 每个子类的实例都持有父类的实例方法的副本,浪费内存,影响性能,而且无法实现父类的实例方法的复用。

       每次创建mango实例,都要创建其私有的eat函数。有多少个mango实例,就创建多少个eat函数。无法实现eat函数的复用。

  • 相关阅读:
    Yield Usage Understanding
    Deadclock on calling async methond
    How to generate file name according to datetime in bat command
    Run Unit API Testing Which Was Distributed To Multiple Test Agents
    druid的关键参数+数据库连接池运行原理
    修改idea打开新窗口的默认配置
    spring boot -thymeleaf-url
    @pathvariable和@RequestParam的区别
    spring boot -thymeleaf-域对象操作
    spring boot -thymeleaf-遍历list和map
  • 原文地址:https://www.cnblogs.com/sea-breeze/p/10189126.html
Copyright © 2011-2022 走看看