前端实现继承的几种方式

原型链的基本构想: 如果原型是另一个类型的实例呢?那就意味着这个原型本身有一个内部指针指向另一个原型,相应地另一个原型也有一个指针指向另一个构造函数 。一、原型链继承构造函数、原型和实例的关系: 每个构造函数都有一个原型对象,原型有一个属性指回构造函数,而实例有一个内部指针指向原型 。
原型链的基本构想: 如果原型是另一个类型的实例呢?那就意味着这个原型本身有一个内部指针指向另一个原型,相应地另一个原型也有一个指针指向另一个构造函数 。这样就在实例和原型之间构造了一条原型链 。
重点: 让新实例的原型等于父类的实例 。
 【前端实现继承的几种方式】function SuperType() {this.property = true}SuperType.prototype.getSuperValue = https://www.isolves.com/it/cxkf/qd/2023-02-08/function () {return this.property}function SubType() {this.subproperty = false}// 继承 SuperTypeSubType.prototype = new SuperType()SubType.prototype.getSubValue = function () {return this.subproperty}let instance = new SubType()console.log(instance.getSuperValue()) // true特点:

  1. 实例可继承的属性有:实例的构造函数的属性,父类构造函数属性,父类原型的属性 。
缺点:
  1. 新实例无法向父类构造函数传参 。
  2. 继承单一 。(只能继承一个父类构造函数)
  3. 所有新实例都会共享父类实例的属性 。(原型上的属性是共享的,一个实例修改了原型属性,另一个实例的原性也会被修改!)
  4. 要想为子类原型新增属性和方法,必须要在new SuperType()这样的语句之后执行
代码如下:
 function SuperType() {this.colors = ["red", "blue", "green"]}function SubType() {}// 继承 SuperTypeSubType.prototype = new SuperType()let instance1 = new SubType()instance1.colors.push("black")console.log(instance1.colors) // "red,blue,green,black"let instance2 = new SubType()console.log(instance2.colors) // "red,blue,green,black"二、借用构造函数继承重点: 用.call()和.Apply()将父类构造函数引入子类函数(在子类函数中做了父类函数的自执行(复制))
 function SuperType(name) {this.name = name}function SubType() {// 继承 SuperType 并传参SuperType.call(this, "Nicholas")// 实例属性this.age = 29}let instance = new SubType()console.log(instance.name) // "Nicholas";console.log(instance.age) // 29复制代码特点:
  1. 只继承了父类构造函数的属性,没有继承父类原型的属性 。
  2. 解决了原型链继承缺点 1、2、3 。
  3. 可以继承多个构造函数属性(call 多个) 。
  4. 在子实例中可向父实例传参 。
  5. 解决了引用值问题
缺点:
  1. 只能继承父类构造函数的属性 。
  2. 无法实现构造函数的复用 。
  3. 每个新实例都有父类构造函数的副本,臃肿 。
三、组合继承(组合原型链继承和借用构造函数继承)(常用)重点: 结合了两种模式的优点,传参和复用
 function SuperType(name) {this.name = namethis.colors = ["red", "blue", "green"]}SuperType.prototype.sayName = function () {console.log(this.name)}function SubType(name, age) {// 继承属性SuperType.call(this, name) //// 第一次调用 SuperType()this.age = age}// 继承方法SubType.prototype = new SuperType() // 第二次调用 SuperType()SubType.prototype.sayAge = function () {console.log(this.age)}let instance1 = new SubType("Nicholas", 29)console.log("instance1=>", instance1)instance1.colors.push("black")console.log(instance1.colors) // "red,blue,green,black"instance1.sayName() // "Nicholas";instance1.sayAge() // 29let instance2 = new SubType("Greg", 27)console.log(instance2.colors) // "red,blue,green"instance2.sayName() // "Greg";instance2.sayAge() // 27特点:
  1. 可以继承父类原型上的属性,可以传参,可复用 。
  2. 每个新实例引入的构造函数属性是私有的 。


    推荐阅读