深刻理解JavaScript中的继承:原型链篇

 

1、何为原型链chrome

  原型是一个对象,当我调用一个对象的方法时,若是该方法没有在对象里面,就会从对象的原型去寻找。JavaScript就是经过层层的原型,造成原型链。函数

2、谁拥有原型测试

  任何对象均可以有原型,当咱们建立对象的时候,会自动为对象添加一个属性,这个属性就是原型,咱们没法访问到他,但在firefox和chrome中能够经过一个非标准的属性__proto__(双下划线)来访问到原型(或经过Object.getPrototypeOf来访问)。firefox

3、理解原型链prototype

  咱们先从如下代码入手对象

  var foo = {};继承

  console.log(foo.toString());// [object Object]  
  console.log(foo.__proto__);// object { ...}  这里指向Object.prototypeip

  foo里面明明没有toString方法,但我却能调用,这就是原型链的做用。当我调用foo.toString时,因为在里面找不到toString方法,那么我从__proto__属性里面去找,找到后并调用。上面的代码中咱们就是从Object.prototype中找到了toString方法。你可能会很困惑,prototype是什么?咱们不要被prototype所迷惑,他只是一个存放属性的容器而已,你能够以下这样作来实现继承(但尽可能不要这么作)原型链

 

function Bar() {}get

Bar.test = {

  say: function () {

      console.log('say test');    

    } 

}

 

var foo = new Bar();

foo.say(); // 报错

 

// 改变继承的对象

 

foo.__proto__ = Bar.test;

foo.say() // say test

  在上面的代码中咱们经过new的形式来建立一个对象,在new的过程当中对象会将__proto__指向函数的prototype,因为prototype中是没有say函数的,因此调用会报错,可是以后咱们强行改变了继承的对象,将foo的继承对象改成Bar.test,因此咱们就能调用say函数了。

 

  我想你已经明白个大概了,prototype事实上并无什么特殊的,硬要说有什么特殊的话,他只是被JavaScript默认为原型属性的存放点而已,他本质上只是个对象,原型链的重点就在于__proto__,你能够试着把__proto__看成桥梁,当我在对象内部找不到属性时,我就会经过这座桥梁到对面的对象里去寻找属性,直到找到为止或者对象里没有桥梁时才停下来。JavaScript就是经过这样的方式来造成原型链,实现继承的关系。

  最后说一下,__proto__只是方便咱们查看对象的原型而已,你们不要经过修改__proto__来实现继承的关系,而是要用如构造函数之类的方式来实现继承,这个我会放到之后的文章去说。

(ps:可能有动手能力强的同窗会本身去测试,发现__proto__里面也有__proto__,一直循环下去,无穷无尽,但事实上你去获取的时候你会发现Object.__proto__.__proto__.__proto__的值是null,也就是没有原型。)

相关文章
相关标签/搜索