每一个函数(箭头函数除外)都有一个原型属性,指向原型。每个对象(null除外)都有一个__proto__属性,该属性指向创建该对象的构造函数的原型。(注意:函数也是对象)对象可以使用__proto__来寻找不属于对象的属性。__proto__连接对象以形成原型链。理解原型和原型链,下图很重要:根据上图,可以得到如下等式://1.对象的__proto__指向其构造函数的原型f1.__proto__===Foo.prototype//2.对象的__proto__指向其构造函数的原型f2.__proto__===Foo.prototype//3.Foo.prototype的本质是一个对象,其构造函数为ObjectFoo.prototype.__proto__===Object.prototype//4.Foo是一个普通的函数(函数也是一个对象,所以它有__proto__属性),它的构造函数是FunctionFoo.__proto__===Function.prototype//5.这个特殊而合理。Funcion既是对象又是函数(而且不是普通函数,它是所有普通函数的构造函数)。//因为是对象,所以它有一个__proto__属性,指向它的构造函数(self)的原型。Function.__proto__===Function.prototype//6.同3Function.prototype.__proto__===Object.prototype//7.对象是所有对象的构造函数,它是一个函数,函数的构造函数isFunctionObject.__proto__===Function.prototype//8.所有的对象最终都会沿着原型链找到Object.prototype,而Object.prototype.__proto__=null就是原型链的末端Object.prototype.__proto__===null上面的等式一切都清楚之后,还应该推导出下面的等式:.__proto__.__proto__===null其实在做推导的时候,把握几个关键点,才不容易混淆:函数也是对象。看到x.__proto__,你一定会把x看成一个对象(即使是Function),然后就会想到“对象的__proto__指向它的构造函数的原型”,看到x.prototype,你一定会想到x必须是一个函数。x.prototype作为一个整体代表了函数x的原型,其实就是一个对象。
