js 原型 _proto_, prototype, contructor的联系

困扰了本人好久的原型,很让人头疼,苦心钻研后,总结如下:

下面理解下:

需要记住几点: 记住!!!记住!!!记住!!!(重要的说3遍)

1. 实例的_proto_属性指向构造函数的原型

2. Function的构造函数是它自己

3._proto_和contructor属性是对象所独有的

4.prototype属性是函数所独有的,因为函数也是一种对象,所以函数也拥有_proto_和contructor属性

 

现在正式开始!让我们从如下一个简单的例子展开讨论,并配以相关的图帮助理解:

function Foo() {...};

let f1 = new Foo();

以上代码表示创建一个构造函数Foo(),并用new关键字实例化该构造函数得到一个实例化对象f1。虽然是简简单单的两行代码,然而它们背后的关系却是错综复杂的,如下图所示: 

js 原型 _proto_, prototype, contructor的联系

 

 重要的有两点:

一、 创建一个function的过程

Javascript 语言中,constructor 属性是专门为 function 而设计的,它存在于每一个 function prototype 属性中。这个 constructor 保存了指向 function 的一个引用。

在定义一个函数(代码如下所示)时,

 

function F() {

// some code

}

 JavaScript 内部会执行如下几个动作:

 

为该函数添加一个原形(即 prototype)属性

prototype 对象额外添加一个 constructor 属性,并且该属性保存指向函数F 的一个引用

 

     

js 原型 _proto_, prototype, contructor的联系

这样当我们把函数 F 作为自定义构造函数来创建对象的时候,对象实例内部会自动保存一个指向其构造函数(这里就是我们的自定义构造函数 F)的 prototype 对象的一个属性proto

 

所以我们在每一个对象实例中就可以访问构造函数的 prototype 所有拥有的全部属性和方法,就好像它们是实例自己的一样。当然该实例也有一个 constructor属性了(从 prototype 那里获得的),每一个对象实例都可以通过 construtor 对象访问它的构造函数

     

 二、new的理解

按照《悟透javascript》书中说的,new形式创建对象的过程实际上可以分为三步: 
第一步是建立一个新对象(叫A吧);

第二步将该对象(A)内置的原型对象设置为构造函数(就是Person)prototype 属性引用的那个原型对象;

第三步就是将该对象(A)作为this 参数调用构造函数(就是Person),完成成员设置等初始化工作。

其中第二步中出现了一个新名词就是内置的原型对象,注意这个新名词跟prototype对象不是一回事,为了区别我叫它inobj,inobj就指向了函数Personprototype对象。在personprototype对象中出现的任何属性或者函数都可以在one对象中直接使用,这个就是javascript中的原型继承了。

又头晕了,上图吧!

js 原型 _proto_, prototype, contructor的联系

这样one对象通过内置的原型对象inobj就可以直接访问Personprototype对象中的任何属性与方法了。这也就解释了上面的代码中为什么one可以访问form函数了。因为prototype对象中有一个constructor属性,那么one也可以直接访问constructor属性。

 

new操作符具体干了什么呢?其实很简单,就干了三件事情。

 

 var obj  = {};

 

obj.__proto__ = Base.prototype;

 

Base.call(obj);

 

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wspxzp.html