• 324 借用构造函数继承


    复习 call 的基本实现原理

    1. call 能改变函数的 this
    2. call 的第一个参数是 this, 后面的参数都是无限的
    const obj = {
      name: "jack",
    };
    
    function getB(x, y) {
      console.log(this, x, y);
    }
    
    Function.prototype.myCall = function (self) {
      const args = Array.from(arguments);
      // 给 对象的原型上添加一个 getB
      self.__proto__.func = this;
      // 对象调用 getB,this 改为 对象
      const res = self.func(...args.slice(1));
      delete self.__proto__.func;
      return res;
    };
    
    getB.myCall(obj, 1, 2); // obj 1 2
    

    借用构造函数继承的实现原理

    核心:利用 call 或者 apply 方法改变父类 this 在作用域中的指向,在子类中对父类调用这个方法,就是将子类的变量在父类中执行一遍。

    缺点一:相同属性后者会覆盖前者

    // 声明父类
    function Parent(id) {
      this.books = ["JavaScript", "html", "css"];
      this.id = id || "";
    }
    // 声明母类
    function Monther(id) {
      this.books = ["UI", "JAVA"]; // 后面的会覆盖前面相同的属性
      this.id = id || "";
    }
    //声明子类
    function Child(id) {
      console.log("call改变原实例的this指向", this);
      Parent.call(this, id); //call改变父类this作用域名的指向
      Monther.call(this, id); //call改变母类this作用域名的指向,但是相同属性后者会覆盖前者
    }
    
    var test1 = new Child(11);
    var test2 = new Child(12);
    
    console.log("---------------------输出测试实例1----------------------");
    console.log(test1);
    console.log("---------------------输出测试实例2----------------------");
    console.log(test2);
    

    缺点二:无法继承 父类声明在原型的方法

    如果想要继承父类的原型方法就必须绑定在 this 上面,这样创建出来的每一个实例都会单独拥有一份而不能共用,这样就违背了代码复用的原则。

    //声明父类
    function Parent(id) {
      this.books = ["JavaScript", "html", "css"];
      this.id = id || "";
      // this.showBooks = function() {
      //     console.log(this.books);
      // }
    }
    //父类声明原型方法
    Parent.prototype.showBooks = function () {
      console.log(this.books);
    };
    
    //声明子类
    function Child(id) {
      console.log("call改变原实例的this指向", this);
      Parent.call(this, id); //call改变父类this作用域名的指向
      Monther.call(this, id); //call改变母类this作用域名的指向,但是相同属性后者会覆盖前者
    }
    
    var test1 = new Child(11);
    // test1.showBooks(); // test1.showBooks is not a function
    

    总结:

    1. Parent.call(this,id)是构造函数式的精髓,由于 call 这个方法可以更改函数的作用环境,
    2. 因此在子类中,对 Parent 调用这个方法,就是将子类的变量在父类中执行一遍,
    3. 由于父类中是给 this 绑定属性的,因此子类自然就继承了父类的共有属性。由于这种类型的继承没有涉及 prototype, 所以父类的原型方法自然就不会被子类继承。
    4. 如果想要继承父类的原型方法就必须绑定在 this 上面,这样创建出来的每一个实例都会单独拥有一份而不能共用,这样就违背了代码复用的原则。
    5. 为了综合之前两种模式的有点于是有了组合式继承
  • 相关阅读:
    python中的time模块
    CSS 布局
    8 Function类型
    2 node 核心
    1 node 简介
    13 对象
    JS 算法一
    JS 模块化
    1 谈谈section标签
    JS 练习一
  • 原文地址:https://www.cnblogs.com/ifon/p/16052182.html
Copyright © 2020-2023  润新知