上周一面试腾讯,面试的题很根底,我自认为我的根底还算不错,然而...如同不是。看一下题吧

[].__proto__ === ?[].__proto__.__proto__ === ?[].__proto__.__proto__.__proto__ === ?

平时关注原型链关注的最多的就是函数,素来没有想过数组的原型链,看到了本人根底的破绽。
讲原型链,就先从原型讲起吧,以下内容就是我学习原型和原型链之后对这块的了解。
如有谬误,望斧正~


1.原型

每个函数都会创立一个prototype属性,这个属性是一个对象,蕴含应该由特定援用类型的实例共享的属性和办法。实际上,这个对象就是通过调用构造函数创立的对象的原型。 --《Javascript高级程序设计》

下面这句话能够失去三个信息:

  1. 当咱们创立一个函数的时候,就会随之创立一个prototype属性,这个属性是一个js对象。(同时原型对象会取得一个constructor的属性,也是一个对象,指向相干的构造函数自身,例如:Person.prototype.constructor === Person;)
  2. 原型的用途是:在原型上的办法和属性能够被对象实例共享。比如说想给数组定义一个办法,让所有创立进去的数组应用,那就能够在Array.prototype上定义;
  3. 对象实例的__proto__指向构造函数的prototype。

到这我对原型就有了一个大略的理解。然而我还搞不懂一个问题,不是说“每个函数都会创立一个prototype属性”吗?Array是一个数组对象,为什么它会有prototype属性。
对于这个问题,我看了一下MDN,如图:

Array 结构器会依据给定的元素创立一个 JavaScript 数组,然而当仅有一个参数且为数字时除外。咱们创立数组的时候能够间接[]创立,也能够new Array()创立。
也就是说对于Array(),是我的了解谬误,它并不是一个数组,而是一个构造函数,那么它有prototype属性也就不难理解啦。

2.原型链

这里还是援用书上的话对原型链做出解释吧。

重温一下构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型有一个属性指回构造函数,而实例有一个外部指针指向原型。如果原型是另一个类型的实例呢?那就意味着这个原型自身有一个外部指针指向另一个原型,相应地另一个原型也有一个指针指向另一个构造函数。这样就在实例和原型之间结构了一条原型链。这就是原型链的根本构想。--《Javascript高级程序设计》

也就是说每个由构造函数创立进去的实例对象都有一个隐式原型__proto__,指向构造函数的原型prototype,并且这个原型也有一个__proto__属性,就这样始终向上,直到止境null。

到这里其实面试题的答案就曾经进去了,我把以上总结为谁的__proto__指向实例对象的prtotype。其中的非凡状况是:Function的__proto__指向本身的prototype,
Object的prototype的__proto__指向null。

依照我的论断再看看面试题:

[].__proto__ === ?[].__proto__.__proto__ === ?[].__proto__.__proto__.__proto__ === ?

答案应该顺次为Array.prototype,Object.prototype,null

第一个应该很好了解,[]是new Array()创立进去的,所以[].__proto__就指向了Array的原型prototype;
第二个由第一个能够转换为Array.prototype.__proto__,在原型那块说过prototype是一个js对象,那还能够转换为Object.__proto__,最初就是Object.prototype
第三个就是Object.prototype.__proto__,也就是null。


过后不会这个题的时候我对面试官说不太理解数组的原型,函数和对象的还能够,而后又给我出了个题,也不会。。。。

({}).__proto__ === ?

当初看很显著了,就是Object.prototype。为啥用括号括起来呢,为了避免报错。