JS 中 prototype constructor __proto__之间的关系

在JavaScript 中,prototype  constructor  __proto__三者之间的关系困扰了很多人,

接下来就理理他们之间剪不断理还乱的关系 

简单理解,某个对象的constructor属性返回该对象构造函数,其__proto__属性是个对象,值和其构造函数的prototype属性值一致,  prototype理解是原型

 

prototype 是“原型”, js的所有函数都有一个prototype属性 ,其属性值是个对象 ,prototype对象中包含构造函数定义的属性和方法,通过该构造函数创建的实例对象都有构造函数提供的属性和方法

var  Cat  =  function(){

  this.like = '爱吃鱼',

  this.hobby = '爱睡觉'

}

var lucky = new Cat();

console.log(lucky);

 

var xiaohei = new Cat();

console.log(xiaohei);

 

lucky 和 xiaohei 都是通过Cat 构造函数创建的,他们都继承里Cat 的属性 hobby ,like(可以理解为他们都继承了猫的特性,爱吃鱼,也爱睡觉,当然继承的对象属性是可以修改的)

 prorotype的主要作用简单来说就是“便于方法或者属性的重用”,可以利用prototype添加扩展属性和方法,

Cat.ptototype.show = function(){

  console.log(this.hobby);

}

Cat.prototype.color = 'orangle'

var c = new Cat();

a.show();   //爱睡觉

 

console.log(c.__proto__ === Cat.prototype); // true 对象c的__proto__值取自构造函数Cat的prototype值
console.log(c.constructor === Cat); // true  对象c的构造函数是Cat
console.log(Cat.prototype.constructor === Cat); // true 

 

我们通过c.show()调用了show方法,但是show方法并不显示在对象本身属性里(可通过hasOwnProperty验证),为何能用?又是__proto__!所有的实例对象都有个__proto__属性,我们看到它的值跟Cat.prototype一致,也就是说实例c继承了Cat类的属性方法。本身的属性里找不到show方法,自动去__proto__中寻找。

 

我们的 c.constructor返回的是c的构造函数,也就是Cat,其实实例对象c本身并没有constructor属性,但是c中的__proto__拥有constructor属性,没错,c本身没有,就会从它的__proto__属性中寻找constructor方法,如果还没有,就继续从__proto__属性的__proto__属性中寻找... 这样就构成了一个原型链。

 

其实new方式的核心实现要分为三个步骤

 

var c = {};                                  //1

c.__proto__ = Cat.prototype;   //2

Cat.call(c);                                //3

return c;                                    //4

第一步:创建一个空对象obj。

第2步: 将新生成的对象的__prop__属性赋值为构造函数的prototype属性,使得通过构造函数创建的所有对象可以共享相同的原型。这意味着同一个构造函数创建的所有 对象都继承自一个相同的对象,因此它们都是同一个类的对象。

小贴士:在JavaScript标准中,并没有__prop__这个属性,不过它现在已经是一些主流的                JavaScript执行环境默认的一个标准属性,用于指向构造函数的原型。该属性是                  默认不可见的,而且在各执行环境中实现的细节不尽相同,例如IE浏览器中不存在该属性。我们只要知道JavaScript对象内部存在指向构造函数原型的指针就可                  以了,这个指针是在调用new表达式的时候自动赋值的,并且我们不应该去修改                  它。

第3步:将构造函数的作用域赋给新对象,因此Cat函数中的this指向新对象c,然后再调用show函数。于是我们就给c对象赋值了成员变量like,hobby。

第4步:返回新对象obj。

 

 

最后总结

javascript中每个对象除了本身的属性外,还有一个__proto__属性,继承了父对象的方法和属性(形成原型链);而每个函数有个prototype属性,该属性值是个对象,该对象函数自定义的一些属性方法外,还有两个属性,constructor(其值一般为函数本身)和__proto__(其值继承自父对象)。

 

posted @ 2019-07-29 17:35  滥好人儿  阅读(155)  评论(0编辑  收藏  举报