先看一段代碼:
varPerson=function( ) {
}
varp=newPerson( );
p.__proto__=Person.prototype
alert(p.__proto__===Person.prototype);//true
這段代碼會返回true。
? ? ? 那么__proto__是什么?我們在這里簡單地說下。每個對象都會在其內部初始化一個屬性,就是__proto__,當我們訪問一個對象的屬性時,如果這個對象內部不存在這個屬性,那么他就會去__proto__里找這個屬性,這個__proto__又會有自己的__proto__,于是就這樣一直找下去,也就是我們平時所說的原型鏈的概念。
好,概念說清了,讓我們看一下下面這些代碼:
這段代碼很簡單,相信每個人都這樣寫過,那就讓我們看下為什么p可以訪問Person的Say。
//變量方式構造函數
varPerson=function() { };
Person.prototype.Say=function() {
alert("Person say");
}
var p=new Person();
p.Say();
? ? ? ?首先var p=new Person();可以得出p.__proto__=Person.prototype。那么當我們調用p.Say()時,首先p中沒有Say這個屬性,于是,他就需要到他的__proto__中去找,也就是Person.prototype,而我們在上面定義了Person.prototype.Say=function(){}; 于是,就找到了這個方法。
Firefox圖示:
好,接下來,讓我們看個更復雜的。
varPerson=function() { };
Person.prototype.Say=function() {
alert("Person say");
}
Person.prototype.Salary=50000;
varProgrammer=function() { };
Programmer.prototype=newPerson();
Programmer.prototype.WriteCode=function() {
alert("programmer writes code");
};
Programmer.prototype.Salary=500;
varp=newProgrammer();
console.log(p)
p.Say();
p.WriteCode();
alert(p.Salary);
Firefox控制臺示意圖:
var p=new Programmer()可以得出p.__proto__=Programmer.prototype;
而在上面我們指定了Programmer.prototype=new Person();我們來這樣拆分,var p1=new Person();Programmer.prototype=p1;那么:
p1.__proto__=Person.prototype;
Programmer.prototype.__proto__=Person.prototype;
由根據上面得到p.__proto__=Programmer.prototype。可以得到p.__proto__.__proto__=Person.prototype。
好,算清楚了之后我們來看上面的結果,p.Say()。由于p沒有Say這個屬性,于是去p.__proto__,也就是Programmer.prototype,也就是p1中去找,由于p1中也沒有Say,那就去p.__proto__.__proto__,也就是Person.prototype中去找,于是就找到了alert(“Person say”)的方法。
其余的也都是同樣的道理。
再來一張stackoverflow上的圖:
個人認為prototype可以當成是一個指針,當new一個方法的時候,指向的都是一個內存區域。
看完這些,感覺對原型鏈的了解應該差不多了吧。
參考原文鏈接:http://www.cnblogs.com/zzcflying/archive/2012/07/20/2601112.html