海棠学院

问:函数岂不是拥有两个原型?
答:是的,函数有两个原型__proto__和prototype。
因为函数是对象,而对象就有原型,其原型就是__proto__。函数是Function的实例,所以此原型就是Function.prototype。
而函数的prototype,不是给自己用的,而是给自己实例用的。

问:到底是构造函数有原型,还是实例有原型?
答:关键是这个“有”字怎么解释。说白了,就是拥有权和使用权的区分。平常我们说话时,并不仔细区分二者。
就像我们经常会说,“你的公司在哪里?”,但我们都知道,公司并不是你的,是属于董事会的,你只是在那上班罢了。
又比如,你有辆跑车,但你从来不开它,却给你的亲朋好友开。你有拥有权,但没使用权。相反,你的好友虽没有拥有权,但有使用权。
从一般语义上来说,构造函数拥有原型,放在自身prototype上,但不是给自身用的,而是给它的实例用的。
从JS的语义上来说,实例对象拥有原型,其内部属性[[prototype]](即__proto__指向)指向构造器的prototype。
另外一点,拥有权是独占的,而使用权是共享的。
因此某一个构造函数的不同实例的原型是同一个。

问:原型链的终点是什么?
答:Object.prototype。它是个对象,它的原型是null。

问:函数都是Function的实例,而Function也是函数,它是谁的实例?
答:它是自身的实例。所以它的__proto__与自身的prototype是同一个东西。而且是个函数,此函数不再有prototype,但是作为对象,它的__proto__是Object.prototype。这是系统内置好的。
Function是Function自身的实例,对此,很多人都会感觉不可思议。不过想想另外一个不可思议的事情就理解了。它是:
我们竟然可以用大脑来指挥自己的大脑如何思考!

问:Object.__proto__和Object.prototype是什么关系?
答:后者是前者的原型。因为Object是函数,是Function的实例,因此Object.__proto__就是Function.prototype,所以后者是前者的原型。