JavaScript里面继承是怎样实现的?如何避免原型链上的对象被共享?

142 0

JavaScript里面继承是怎样实现的?

最简单的就是通过原型链继承,然后衍生出几种方法:构造函数继承、组合继承、原型式继承、寄生继承、寄生组合式继承。

function Box() {
  this.name = "鱼儿",
  this.age = 666
}
Box.prototype.run = function(){
   return this.name;
}
function Pox() {
  this.run = function() {
    alert(this.name + this.age);
  }
}
Pox.prototype = new Box();
var pox1 = new Pox();

通过Pox的prototype继承Box构造函数,那么这里Pox.prototype = new Box();发生了什么呢?

首先new Box()会创建一个新的对象,然后将Box的this指向这个对象,这个对象因此会获取到Box构造函数的方法和原型,然后返回出这个对象。

此时Pox.prototype =这里就发生了“赋值”操作,Pox原有的原型被覆盖成new Box()返回的新对象,Pox原型如果之前有方法就会消失。

这里其实可以再理解为,Pox的prototype等于Box的prototype;因为原型的特殊,这里的等于并不是实际的等于,他是相当于将Pox的prototype指向Box的prototype,而其原有的内容则删除了。

又因为原型的constructor的指针指向构造函数本身,因此,Pox也可以获取到Box的独立属性this.name和this.age,那么,这个就是所谓的原型链上的对象共享了。

如何避免原型链上的对象被共享?

通过call方法,将Box的独立属性复制一份到Pox上,这样Pox就可以在创建的独立环境中拥有Box的独立属性,而且不与其他子类共享。

function Box() {
  this.name = '鱼儿',
  this.age = 666
}
Box.prototype.run = function(){
   return this.name;
}
function Pox() {
  Box.call(this)
  this.run = function() {
    alert(this.name + this.age);
  }
}
Pox.prototype = new Box();
var pox1 = new Pox();
var pox2 = new Pox();

这样pox1和pox2 的this.name和this.age其实是相互独立的,而且和Box也是独立的,他们三个任何一个独立属性改变都不会相互有影响。

但是后面的Pox.prototype = new Box();实际上还是获取到了Box的独立属性,因为原型的constructor指针的关系,但是原型链之间的获取是有顺序的,也就是优先在Pox的独立属性中查找-----然后到Pox的原型查找---然后再到Box的独立属性,但是因为我们call了一份相同的内容下Pox独立属性里面,所以每次获取值都是获取到Pox下的,这就可以达到不共享了。

然后更加完美点的就是寄生组合式继承,多了一个中转函数和寄生函数,具体我自己也还不是特别懂,后期再讲吧!

0

相关文章

微信收款码
微信收款码