prototype和__proto__ 的爱恨情仇

590 阅读1分钟

原型和原型链一直都是JavaScript老生常谈容易让人模糊不清的概念,但是鉴于原型在JavaScript的不可撼动的重要地位,对它们的讨论和理解是永远不过时的话题。

先来理解一下两者的本质区别:

  • prototype是函数独有的,是人为设定的
  • __proto__是所有对象都有的,是继承的

先讲一个故事休息一下:long long ago,在ECMAScript的世界里,宇宙一片虚无,后来诞生了一个叫 ObjectPrototype的上古第一个生灵,也就是 Object.prototype。它是万物的尽头,继承于虚无,也就是 Object.prototype.__proto__ = null

接着,由这个上古生灵衍生出了第二个上古大神,FunctionPrototype,也就是 Function.prototype。于是有了 Function.prototype.__proto__ === Object.prototype // true Function.prototype 本身也是个函数对象,这是为了兼容 ES5。也估计是让人引起误解的源头。但两者还是不同的,这是个特殊的函数对象,它忽略参数总是返回 undefined,且没有 [[Construct]] 内部方法。 自从诞生了这两个上古大神,于是修道成神的时代开启了,世界逐渐形成的更加完善。相信大家也都听说了函数是js世界里的“一等公民”,是因为,他们都是FunctionPrototype孕育出来的子民。(这里没有用 Function.prototype 是为了避免混淆,文章开头说了,prototype 是人为设定的),包括Function自身。所以下面的结果就很容易理解了

接下来的问题就容易多了,比如 Object instanceof Object。前面我们知道 Object.__proto__是 FunctionPrototype,而它的__proto__是上古第一生灵 ObjectPrototype,恰好也是 Object.prototype,所以就是 true,其它的也是同理,举一反三很简单了。