JavaScript中prototype和__proto__

  prototype和__proto__是比较容易混淆的两个属性,在介绍这两个属性之前,首先要介绍一下JS中的原型对象:  

  当我们在JS中定义了一个函数之后,JS会自动为该函数添加一个prototype属性,该属性指向当前函数的原型对象,而在原型对象中有一个属性:constructor,该属性会指向该原型对象所属的函数,如果该函数是构造函数(构造函数本身其实就是普通函数,构造函数名字首字母大写是我们默认的书写规范,JS中并没有这个规定),我们通过构造函数new了一个实例,那么该实例中会有一个[[prototype]]属性,该属性指向构造函数的原型对象,但是这个属性我们是无法直接访问的,也就是该属性对外是隐藏的, 但是主流浏览器为了使用该属性, 添加了一个__proto__属性, 通过__proto__就可以访问实例中的[[prototype]]属性了。

  __proto__指向的是当前实例的构造函数的原型对象,或者说是父类的原型对象,而prototype指向的是当前函数的原型对象。

在JS中万事万物都是对象,包括我们定义的函数以及函数的原型对象,其实都是对象。

自定义函数F():

当我们自定义一个函数时,该函数的prototype会指向自己的原型对象,例如上图中的F(),F.prototype属性指向F.prototype,而F.prototype.constructor又指向构造函数F(),f1是通过F()new出来的实例,因此他的__proto__属性指向构造函数的原型对象,也就是F.prototype。

JS中Object又是一切对象的最终父类,就向java中所有的类都默认继承于Object类是一个道理,所以F.prototype也是Object的实例,那么F.prototype的__ptoto__属性就会指向他的构造函数的原型对象,也就是Object.prototype,那么Object.prototype指向谁呢?答案是null,到这里已经到头了。

既然前面已经说了,JS中万事万物都是对象,那么我们自己定义的函数也是一个对象,是对象就会有构造函数,那自定义函数的构造函数是谁呢,答案是Function(),所以自定义函数的__proto__指向Function.prototype。而Function本身也是一个对象,继承于Object对象,所以Function.prototype属性指向Object.prototype。

 

总结:

1、__proto__是实例的属性,而prototype是对象的属性,__proto__总是指向构造函数的原型对象, 而prototype指向本身的原型对象。

2、所有函数的构造函数都是function Function(),包括Object(),因此只要是使用了function关键字的,他的__proto__就指向Function.prototype。

3、所有的对象最终都继承于Object对象,所以所有函数的原型对象最后都会指向Object.prototype。

4、JS中通过原型链继承实际上是通过__proto__属性实现的,而不是prototype属性。

posted on 2019-03-12 15:50  观琪不喻  阅读(130)  评论(0)    收藏  举报

导航