[JavaStript學習記錄] 對建構函式,原型,例項物件的一些理解
回憶一下昨天的學習內容,梳理一些疑惑
先寫了一個簡單的建構函式
function A(){
var num=0;
}
var aa=new A();
檢視該函式的例項
發現
1.aa是A的一個例項,但是不是一個函式,所以沒有prototype;A是Function的一個例項,而Function是一個函式,他的例項A也是一個函式,所以他們都有prototype。此外Object ,Array, RegExp等也是函式。Math就僅僅是一個new Object(),不是函式。
2.建構函式的prototype,預設情況下就是一個new Object()還額外添加了一個constructor屬性。
3.除了Object.prototype這個物件,其他所有的物件都會有__proto__屬性,之後函式才會有prototype屬性。
在建立物件的時候會自動建立一個__proto__
屬性,指向它建構函式的prototype
,當訪問這個物件的屬性的時候會順帶訪問__proto__
中對應的屬性,也就是建構函式prototype
這樣實現了繼承。
只有建立函式的時候才會建立一個prototype
屬性,目的就是為了完成上面的繼承方式。
總結:
每個建構函式[自動帶有一個prototype屬性,該屬性是一個指標,指向一個物件(即原型物件)]都有一個原型物件,原型物件上包含著一個指向建構函式的指標(constructor),而例項都包含著一個指向原型物件的內部指標(_proto_)。通俗的說,例項可以通過內部指標訪問到原型物件,原型物件可以通過constructor找到建構函式。
回顧原型鏈
function People(){
this.type = '人';
}
People.prototype.showType = function(){
alert(this.type);
}
function Man(){
this.sex='♂';
this.age=18;
}
Man.prototype=new People();
var boy=new Man();
console.log('大家好,我'+boy.age+'歲啦,性別為'+boy.sex+'我是'+boy.type+'族的一員');
>>大家好,我18歲啦,性別為♂我是人族的一員
將Man建構函式的prototype指向了People例項物件,從而覆蓋了Man的原型物件。當Man的例項物件boy去訪問type屬性時,js首先在Man例項屬性中查詢,發現沒有定義,接著去Man的原型物件上找,Man的原型物件此時已被改成了People例項,那就是去People例項上去找。先找People的例項屬性,發現沒有type,最後去People的原型物件上去找,找到了。這個查詢就是這麼一級一級的往上查詢。
function People(){
this.type = '人';
}
People.prototype.showType = function(){
alert(this.type);
}
function Man(){
this.sex='♂';
this.age=18;
this.type = '狂戰士';//此處定義了type屬性,就不會向上層級查詢;
}
Man.prototype=new People();
var boy=new Man();
console.log('大家好,我'+boy.age+'歲啦,性別為'+boy.sex+'我是'+boy.type+'族的一員');
>>大家好,我18歲啦,性別為♂我是狂戰士族的一員
我們通過原型鏈的方式,實現 Man繼承 People 的所有屬性和方法。
總的來說:就是當重寫了Man.prototype指向的原型物件後,例項的內部指標也發生了改變,指向了新的原型物件,然後就能實現類與類之間的繼承了。