JS 继承

bb刀

JS的六种继承方式

1.借助call / apply
// 父函数
function P(){
  this.arr = [1,2,3]
}

// 子函数
function C(){
  P.call(this)
}

缺点:这种继承方式子类可以继承父类的属性值,但是子类是无法继承父类存在的原型链上的方法。所以可以引出借助原型链的方式。

2.借助原型链

function P(){
  this.arr = [1,2,3]
}

function C(){
}

C.prototype = new P()
console.log(C)

var c = new C()
var c2 =new C()
c.arr.push(4)

console.log(c.arr,c2.arr)  / / [1,2,3,4] , [1,2,3,4]

缺点:通过打印我们可以看到2个实例的arr都发生了改变,那为什么会改变了?因为2个实例指向的是同一个原型对象。
那么还有更好的方式吗?

3.将前两种方式组合

function P(){
  this.arr = [1,2,3]
}

function C(){
  P.call(this)
}

C.prototype = new P()
console.log(C)

var c = new C()
var c2 =new C()
c.arr.push(4)

console.log(c.arr,c2.arr)  / / [1,2,3,4] , [1,2,3]

通过控制台可以看到原先的问题解决了,但是又出现一个新的问题,P的构造函数会多执行一次,那么我们怎么去优化它呢?

4.组合继承优化1

function P(){
  this.arr = [1,2,3]
}

function C(){
  P.call(this)
}

C.prototype = P.prototype

var c = new C()
console.log(c)  // P

什么?c的构造函数竟然是P,显然这不是我们想看到的,结果应该是C。

5.组合继承优化2

function P(){
  this.arr = [1,2,3]
}

function C(){
  P.call(this)
}

C.prototype = Object.create(P.prototype)
C.prototype.constructor = C
var c = new C()
console.log(c)  // C

打印结果,构造函数指回到C了。这种继承方式接近于完美,也是我们最常用的组合寄生继承。

你可能感兴趣的:(JS 继承)