为了账号安全,请及时绑定邮箱和手机立即绑定

Js中prototype和__proto__的初步理解

标签:
JavaScript

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

1.首先一切皆对象 

我接下来讲的Object、类A、类B、实例a、实例b、Function、prototype属性、__proto__属性等……都是对象。

2.prototype:原型对象的引用。

__proto__:原型,或者 隐式原型。

(I)先讲原型(即__proto__属性)

https://img1.sycdn.imooc.com//5b599ea60001cc0b03950211.jpg

上图可以看出,一切对象都有原型(__proto__属性)。[除少数几个特殊对象]


https://img1.sycdn.imooc.com//5b59a1470001cb1404250267.jpg

即使是对象的属性(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__属性

https://img1.sycdn.imooc.com//5b59b7bc000170e808160453.jpg

图片有写乱,箭头很多,我来理清一下

(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人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消