js 原型链

记录下本身对js 原型的一些理解
先看一下什么是 ····原型链数组

function Foo(){}
Foo.prototype.num = 3;
// new Foo( ) 将返回一个对象 把这个对象赋值给了 bar 
var bar = new Foo();
// bar 是怎么找到的原型下面的num呢?
alert(bar.num); //3

bar并无num 属性,它是怎么拿到3的呢 此处的 bar 就是经过原型链找到了值
原型链
JavaScript中的对象有一个特殊的 __proto__ 内置属性,其实就是对于其余对象的引用(关联)。当咱们使用 function关键字声明一个函数时,系统会自动建立一个对象,访问这个对象能够经过 函数名.prototype 访问(咱们通常把这个对象叫作原型对象),当使用 new 关键字调用函数(这时咱们通常把这个函数称为构造函数)时其中有一个步骤就是对建立的对象进行原型关联,关联到声明函数时建立的那个对象(函数名.prototype指向的那个对象)函数

上面例子 中使用 new 关键字调用 Foo()函数时会建立一个对象咱们把这个对象赋值给了 bar ; bar对象内部的.__proto__属性会关联到声明函数时建立的那个对象(Foo.prototype) , bar.num属性在bar中没法找到时,就会访问bar.__proto__查找,这个过程会持续到找到匹配的属性名或者查找完整条prototype链(全部普通的[[Prototype]]链最终都会指向内置的Object.prototype)
,所以上面例子的原型链是这样的this

bar.__proto__ -- 指向 --> Foo.prototype --而后(Foo.prototype.__proto__) -- 指向 --> Object.prototype

所以
每一个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么,假如咱们让原型对象等于另外一个类型的实例,结果会怎么样呢?显然,此时的原型对象将包含一个指向另外一个原型的指针,相应地,另外一个原型中也包含着一个指向另外一个构造函数的指针。假如另外一个原型又是另外一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条。这就是所谓原型链的基本概念
对prototype更详细的介绍请看这里(https://developer.mozilla.org...prototype

原型链的问题

包含引用类型值的原型属性会被全部实例共享;(而这也正是为何要在构造函数中,而不是在原型对象中定义属性的缘由)在经过原型来实现继承时,原型实际上会变成另外一个类型的实例。因而,原先的实例属性也就瓜熟蒂落地变成了如今的原型属性了。下列代码能够用来讲明这个问题。指针

function SuperType(){   
  this.colors = ["red", "blue", "green"];
}
function SubType(){}//继承了SuperType
SubType.prototype = new SuperType();
var instance1 =newSubType();
instance1.colors.push("black");
//"red,blue,green,black"
alert(instance1.colors);
var instance2 = new SubType();
//"red,blue,green,black"
alert(instance2.colors);

SuperType构造函数定义了一个colors属性,该属性包含一个数组(引用类型值)。SuperType的每一个实例都会有各自包含本身数组的colors属性。当SubType经过原型链继承了SuperType以后,SubType.prototype就变成了SuperType的一个实例,所以它也拥有了一个它本身的colors属性——就跟专门建立了一个SubType.prototype.colors属性同样。但结果是什么呢?结果是SubType的全部实例都会共享这一个colors属性。而咱们对instance1.colors的修改可以经过instance2.colors反映出来,就已经充分证明了这一点。code

在建立子类型的实例时,不能向超类型的构造函数中传递参数。实际上,应该说是没有办法在不影响全部对象实例的状况下,给超类型的构造函数传递参数。有鉴于此,再加上前面刚刚讨论过的因为原型中包含引用类型值所带来的问题,实践中不多会单独使用原型链对象

相关文章
相关标签/搜索