🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
> * js里所有的对象都有**proto**属性(对象,函数),指向构造该对象的构造函数的原型。 > * 只有函数function才具有prototype属性。这个属性是一个指针,指向一个对象,这个对象的用途就是包含所有实例共享的属性和方法(我们把这个对象叫做原型对象)。原型对象也有一个属性,叫做constructor,这个属性包含了一个指针,指回原构造函数。 要理解原型和原型链首先要知道几个概念: ①、在js里,继承机制是原型继承。继承的起点是 对象的原型(Object prototype)。 ②、一切皆为对象,只要是对象,就会有 proto 属性,该属性存储了指向其构造的指针。 Object prototype也是对象,其 proto 指向null。 ③、对象分为两种:函数对象和普通对象,只有函数对象拥有『原型』对象(prototype)。 prototype的本质是普通对象。 Function prototype比较特殊,是没有prototype的函数对象。 new操作得到的对象是普通对象。 ④、当调取一个对象的属性时,会先在本身查找,若无,就根据 proto 找到构造原型,若无,继续往上找。最后会到达顶层Object prototype,它的 proto 指向null,均无结果则返回undefined,结束。 ⑤、由 proto 串起的路径就是『原型链』。 ### 三句话总结原型和原型链 > 第一句话:`prototype`是函数的原型对象,即`prototype`是一个对象,它会被对应的`__proto__`引用。 > 第二句话:要知道自己的`__proto__`引用了哪个`prototype`,只需要看看是哪个构造函数构造了你,那你的`__proto__`就是那个构造函数的`prototype`。 > 第三句话:所有的构造函数的原型链最后都会引用`Object`构造函数的原型,即可以理解Object构造函数的原型是所有原型链的最底层,即`Object.prototype.__proto===null` **以下试题帮助您加深理解** ## 第一道: ~~~ Object.__proto__ === ????填空???? // 为 true ~~~     求`Object.__proto__`,首先你要知道`Object`是什么数据类型,他是一个构造函数,也就是一个函数,来复习一下我们的第二句话,函数由哪个构造函数构造出来?那不是废话吗,当然是`Function`,因此很明显,答案就是: ~~~ Object.__proto__ === Function.prototype // 为 true ~~~ ## 第二道: ~~~ Function.__proto__ === ????填空???? // 为 true ~~~     求`Function.__proto__`,一样,你要先清楚`Function`是什么数据类型,他同样是一个构造函数,是来用来创建(构造)一个函数的构造函数(- -!有点拗口),所以同样的,用我们的第二句话即可解决,这个构造函数同样是函数,因此答案就是: ~~~ Function.__proto__ === Function.prototype // 为 true ~~~ ## 第三道: ~~~ true.__proto__ === ????填空???? // 为 true ~~~     求`true.__proto__`,有没有感觉是换汤不换药,`true`是什么数据类型,`Boolean`嘛,因此它是由构造函数`Boolean`构造出来的,所以答案显而易见: ~~~ true.__proto__ === Boolean.prototype // 为 true ~~~ ## 第四道: ~~~ Function.prototype.__proto__ === ????填空???? // 为 true ~~~     求`Function.prototype.__proto__`,好了,这里需要第一句话和第二句话一起用了,首先根据第一句话,`prototype`是一个对象,然后根据第二句话,那么既然它是一个对象,他的构造函数很明显就是`Object`,因此答案也呼之欲出了: ~~~ Function.prototype.__proto__ ===Object.prototype // 为 true ~~~ ## 第五道: ~~~ function Test(){} var test=new Test() test.__proto__===????填空???? // 为 true ~~~     对于自己写的构造函数,这三句话依然有效,因此答案也很容易就得出来了: ~~~ test.__proto__===Test.prototype // 为 true ~~~ ## 最后一道,必须谨记的例外: ~~~ Object.prototype.__proto__===null ~~~