深刻理解javascript原型链

  在javascript中原型和原型链是一个很神奇的东西,对于大多数人也是最难理解的一部分,掌握原型和原型链的本质是javascript进阶的重要一环。今天我分享一下我对javascript原型和原型链的理解。javascript

      1、对象等级划分java

  咱们认为在javascript任何值或变量都是对象,可是我还须要将javascript中的对象分为一下几个等级。数组

  首先Object是顶级公民,这个应该毋庸置疑,由于全部的对象都是间接或直接的经过它衍生的。Function是一等公民,下面会作解释。几个像String,Array,Date,Number,Boolean,Math等内建对象是二等公民。剩下的则都是低级公民。函数

  2、原型prototype工具

  首先prototype是一个属性,同时它自己也是一个对象。那么哪些是具备prototype这个属性呢?其实javascript中全部的函数都有prototype这个属性,反过来全部具备prototype的对象自己也是一个函数,没错就是一个函数。spa

  第一条我再也不印证,主要看看第二条。你们都知道Object,Array,Date都有prototype,他们是函数吗?是的他们也是函数的一种,为何这么说呢?咱们在定义一个对象或者数组时,是否是能够这么作var o = new Object(),a = new Array()。学过java的人都知道new是用实例化一个对象的方法,可是咱们都知道javascript中不存在真正的类的概念,因此只能用函数来模拟,那么既然能够有上面的作法也就印证了Object和Array也是特殊的函数。prototype

  其实上面说到的几等公民基本都是函数的一种,除了Math这个工具对象外,应该没有见过这种new Math()这种写法吧!固然这种写法也是会报错的,因此在访问Math.prototype返回的也是undefined。指针

  3、__proto__和原型链对象

  __proto__是一个指针,它指的是构造它的对象的对象的prototype,听起来有的拗口。举个例子吧!blog

  

  如上面代码,o是Object的一个实例,因此o的__proto__指针指向构造o的Object的prototype。这样的意义在于o能够使用Object.prototype里面的方法,例如toString(),o在访问toString方法时,首先会在自身寻找,若是没有找到则会在__proto__也就是Object.prototype上面查找。

  能够说几乎全部的javascript对象都有__proto__这样一个指针包括Object,咱们来看一看 

  

  其实a = 1就至关于a = new Number(1)。能够看到全部的内建对象以及Object的__proto__指向的都是一个匿名函数,也就能够认为它们其实也是function的一个实例,因此以前会说function是一等公民。

  那么原型链究竟是什么呢?咱们展开a.__proto__也就是Number.prototype对象,它是没有toString()的方法的,可是对于a来讲它实际上是能够调用toString的方法的,这就是原型链的做用。看下面代码

  

  看上面代码和结果,咱们沿着a的__proto__一直访问会到达Object的prototype,也就是说a调用toString方法最终实际上是访问Object.prototype的toString方法。那么a的原型链就是由Number.prototype和Object.prototype组成,当a访问一个方法或属性时,它会先在自身查找,而后再沿原型链找,找到则调用,没找到报错。为了印证这一点,咱们在Number.prototype上面加一个toString的方法。

  

  能够看到a调用的是Number.prototype的toString方法,在找到以后就中止。在javascript中,几乎全部的对象的原型链的终点都是Object.prototype 

  总结

  __proto__是实现原型链的关键,而prototype则是原型链的组成。最后附上一张稍微复杂的原型链和构造函数的关系图,有兴趣能够研究一下。

  

相关文章
相关标签/搜索