3-24 借用构造函数继承

复习 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. 为了综合之前两种模式的有点于是有了组合式继承
posted @ 2022-03-24 21:59  林见夕  阅读(74)  评论(0编辑  收藏  举报