正在加载中

最后更新于 2019年05月13日

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下的,这就可以达到不共享了。

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

  • weixiao kaixin tushetou jingkong deyi fanu liezui liuhan daku ganga bishi nanguo lihai qian yiwen numu tu yi haixiu se fadai minyan hehe henkaixin huaji biyiyan kuanghan maimeng shui xiaku penqi zhangzui pen aini ye niu laji ok chigua renshi kongbu shuai xiaoxiese touxiao huaixiao jingnu chihuai kaisang xiaoku koubi zhuangbi lianhong kanbujian shafa zhijing xiangjiao dabian yaowan redjing lazhu rizhi duocang chixigua hejiu xixi xiaopen goukun xiaobuchu shenme wusuowei guancha lajing chouyan xiaochi bie zhadanzui zhadanxiao

登录