(前方有误导风险,非战斗人员请迅速撤离!)
1.首先:一切皆对象 !
我接下来讲的Object、类A、类B、实例a、实例b、Function、prototype属性、__proto__属性等……都是对象。
2.prototype:原型对象的引用。
__proto__:原型,或者 隐式原型。
(I)先讲原型(即__proto__属性)
上图可以看出,一切对象都有原型(__proto__属性)。[除少数几个特殊对象]
即使是对象的属性(prototype、__proto__),它们也是对象,所以也有原型(__proto__)。
(不过上图也可以看出,Object.prototype就是没有原型的特殊对象)
(II)接下来讲prototype属性
"所有通过对象直接量创建的对象都具有一个原型对象,并可以通过JavaScript代码Object.prototype获得对原型对象的引用。"——犀牛书
像Class A的A、Function、Object、Array、String这些对象,都有一个prototype属性。
但是Class A的实例a没有prototype属性。
原因是:a是new出来,而不是上面的引用里说的“通过对象直接量创建”。
这里不讨论什么是“通过对象直接量创建”,什么是new创建的。请继续往下看。
3.对象的__proto__属性
图片有写乱,箭头很多,我来理清一下
(1)图中有Function、Object、类A、类B这四个对象,它们不仅有__proto__,还有prototype属性
(2)类B继承类A
(3)实例a和实例b,这两个对象只有__proto__属性
下面我们
【1】先看图片中a、b的__proto__
【2】再看Function、Object、A、的__proto__
【3】接着看B的__proto__
【4】再看A.prototype、B.prototype、Function.prototype的__proto__
【5】最后看Object.prototype的__proto__
对象的原型(__proto__)就是构造函数的prototype属性的值
比如:在Es5中,我们new对象是这样子的
function Point(x, y) { this.x = x; this.y = y; } var p = new Point(1, 2); //其中函数Point就是构造函数,所以 cs(p.__proto__ === Point.prototype); //true
【1】看类A的实例a,类B的实例b的__proto__属性。
console.log(a.__proto__ === A.prototype); //true console.log(b.__proto__ === B.prototype); //true
看完我们知道,实例a和实例b的__proto__属性,就是该对象被new出来时,new指向的构造函数的prototype属性。(类A和类B其实就相当于构造函数)
【2】再看图片中Function、Object、Class A的__proto__属性。
Function.prototype === Function.__proto__; //true Function.prototype === Object.__proto__; //true Function.prototype === A.__proto__; //true
可以这样理解:Function、Object、A,这些对象都是由new Function()创造出来的。
所以它们的__proto__就都等于Function这个构造函数的prototype属性。
【3】再看Class B的__proto__属性。
B.__proto__ === A; //true
这里就不能理解成B是由new 什么构造函数了,因为它的__proto__等于A,而不是谁谁谁的prototype属性。
所以说当存在继承关系的时候,子类对象的__proto__指向父类。
【4】再看A.prototype、B.prototype、Function.prototype的__proto__属性。
B.prototype.__proto__ === A.prototype; //true A.prototype.__proto__ === Object.prototype; //true Function.prototype.__proto__ === Object.prototype; //true
这里理解为:子类的原型对象(prototype)的原型(__proto__) === 父类的原型对象(prototype)
B继承A。
A继承Object。
Function继承Object。
【5】最后看Object.prototype的__proto__属性。
Object.prototype.__proto__ === null; //true
这里理解为:Object继承null,
所以Object的原型对象(prototype)的原型(__proto__) === null的原型对象(prototype)
而null就是null,null没有原型对象(prototype),所以还是null,所以null的原型对象(prototype)还是null。所以等于null。
-----------------------------------------------------------
就这样.
什么?没有讲prototype?
__proto__都理清了,就能体会什么是protype了,
其实吧,
prototype就是别人的__proto__
__proto__就是别人的prototype
(一本正经地胡说八道)