从Object和Function说说JS的原型链

  ECMAScript规定了两个特殊的内置对象:Object和Function。他们的特殊性在于,他们自己既是对象又是函数,而他们同时也是对象和函数的构造器。这种本身生本身的逻辑显然违反人性,若是还停留在类的继承的思想上,那么更加没法理解。html

  然而ECMAScript是基于原型链的,因此忘掉类的继承,从原型链入手:原型链是对象的集合,每一个对象都有内部属性[[Prototype]](注1)指向另外一个对象;当访问对象某一属性的时候,若是此属性不为此对象的自身属性(注2),则继续去[[Prototype]]指向的对象上查找此属性。[[Prototype]]造成的对象的链式集合即原型链。这里能够得出:原型链上的全部元素都是对象浏览器

  ECMASciprt规定:原型链必须是有限长度(注3),并且终点必须是null。如今终点是惟一的,那么原型链上倒数第二个元素是否是惟一的呢?ECMAScript没有规定,但从实现上来看,是惟一的。由于原型链上全部的元素都是对象,因此倒数第二个元素应该是全部对象的基础对象。这个对象在实现中只给出一个引用,就是Object.prototype。这里能够得出:原型链上有两个元素是固定的,终点是null,倒数第二的元素是Object.prototype指向的对象(注4)函数

  那么倒数第三个元素是否是固定的呢?不是。从倒数第二个元素是Object.prototype来看,经过{}字面量和new Object()建立的对象都在倒数第三这个位置,即POJO都在倒数第三。另外还有两个特例,一个是除内置函数以外的内置对象,如Math、JSON;一个是除Object以外的内置函数的prototype属性指向的对象,如Function.prototype。这里能够得出:原型链上倒数第三的元素通常是POJO+Math/JSON+(Function/Array/String/Boolean/Number/Date/RegExp/Error).prototypespa

  倒数第三的位置出现了这么多的prototype,那么倒数第四的位置就好推测了,全部除Object以外的内置函数做为构造器调用(注5)时生成的实例对象都在倒数第四。其中须要注意的是,全部的内置函数自己是Function做为构造器调用生成的实例对象,因此都在这个位置。这里能够得出:原型链上倒数第四的元素通常是(Function/Array/String/Boolean/Number/Date/RegExp/Error)实例,其中包括(Object/Function/Array/String/Boolean/Number/Date/RegExp/Error),注意这个括号里面Object回来了prototype

  原型链基本结构以下图:code

 

从图上看来:htm

  1. array等非POJO对象在原型链上和他们的构造器属于同一级别
  2. POJO在原型链上比他的构造器还靠后一个级别

参考文档:ES5对象

注:blog

  1. 内部属性是不开放给JS访问的属性,但现代浏览器已经能够经过__proto__属性访问和设置[[Prototype]]
  2. own property,即直接设置在此对象上的属性
  3. 执行如下代码感觉下:
    var a = {};
    a.__proto__ = a;

     

  4. Object.prototype和基础对象的关系比如快捷方式和应用程序,自己没有任何关系,如今能够指向基础对象,之后也能够指向其余对象。固然原则上是不容许的,基础对象没有引用内存会被回收,因此ECMAScript规定Object下的prototype属性的writable和configuration特性都是false(特性的问题之后另起一篇)
  5. 假设func为一个函数,func()即做为函数调用(调用内部函数属性[[Call]]),new func()即做为构造器调用(调用内部函数属性[[Construct]])
相关文章
相关标签/搜索