JS继承 --每日学习

74 阅读2分钟

前言

继承是js作为面向对象的语言最为重要的一个特性之一,也是面试中经常被问到的一个知识点
继承主要是为了子类可以使用父类的所有功能,并且能对这些功能进行扩展。

1.原型继承

function Parent1() {
  this.name = "parent1"
  this.arr = [1,2,3]
}

Parent1.prototype.say = function(){
  console.log(this.name);
}

function Child1 (){
  this.type = "child1"
}

Child1.prototype = new Parent1()

let child1_1 = new Child1()
let child1_2 = new Child1()

console.log(child1_1.name); // parent1
console.log(child1_1.say()); //parent1

child1_2.arr.push(4)
console.log(child1_1.arr,child1_2.arr); //[ 1, 2, 3, 4 ] [ 1, 2, 3, 4 ]

方式:将子类的原型挂载到父类上 缺点:子类都是通过new构造处理的实例,父类属性没有隔离,会相互影响

2.构造函数继承

function Parent2 (){
  this.name = "parent2"
}
Parent2.prototype.say = function(){
  console.log(this.name);
}

function Child2 (){
  this.type = "child2"
  Parent2.call(this)
}

let child2_1 = new Child2()
console.log(child2_1.say()); // TypeError: child2_1.say is not a function
console.log(child2_1.name); // parent2

方式:通过call、apply、bind将子类函数的this指向父类函数 缺点:只能读取到父类函数的属性,无法继承原型链上的方法和属性

3.组合继承

function Parent3 (){
  this.name = "parent3"
  this.arr = [1,2,3]
}
Parent3.prototype.say = function(){
  console.log(this.name);
}

function Child3 (){
  this.type = "child3"
  Parent3.call(this)
}

Child3.prototype = new Parent3()
let child3_1 = new Child3()
let child3_2 = new Child3()

child3_1.arr.push(4)
console.log(child3_1.arr, child3_2.arr);

方式:通过原型继承和构造继承的组合使用 缺点:call()方法已经拿到父类所有的属性 ,后面再使用原型时也会有父类所有属性;

4.寄生组合继承

function Parent4 (){
  this.name = "parent3"
  this.arr = [1,2,3]
}
Parent4.prototype.say = function(){
  console.log(this.name);
}

function Child4 (){
  this.type = "child4"
  Parent4.call(this)
}

Child4.prototype = Parent4.prototype
Child4.prototype.constructor = Child4
let child4_1 = new Child4()
let child4_2 = new Child4()
child4_1.arr.push(4)
console.log(child4_1.arr, child4_2.arr) // [1, 2, 3, 4]  [1, 2, 3]
console.log(child4_1.constructor === Child4) // true 
console.log(child4_1.constructor === Parent4)// false

说明:解决组合继承重复属性的问题,直接将子类的原型等于父类的原型,或者是用Object.create继承原型但不执行父类构造函数;

5.ES6 class继承

class Parent5{
	constructor(){
  	this.name = 'Parent5'
    this.arr = [1, 2, 3]
  }
  say(){
  	console.log(this.name)
  }
}
class Child5 extends Parent5{
   constructor(){
    super() //通过super()调用父类构造函数
    this.type="Child5"
  }
}
let child5_1 = new Child5()
let child5_2 = new Child5()
child5_1.arr.push(4)
console.log(child5_1.say()) // Parent5
console.log(child5_1.arr, child5_2.arr) // [1, 2, 3, 4]  [1, 2, 3]
console.log(child5_1.constructor === Child5) // true 
console.log(child5_2.constructor === Parent5) // false

就是寄生组合继承的语法糖

学习来源