手记

Js中prototype和__proto__的初步理解

(前方有误导风险,非战斗人员请迅速撤离!)

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】先看图片中ab的__proto__

【2】再看FunctionObjectA、的__proto__

【3】接着看B的__proto__

【4】再看A.prototypeB.prototypeFunction.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

(一本正经地胡说八道)

1人推荐
随时随地看视频
慕课网APP