1. 程式人生 > 其它 >[JavaStript學習記錄] 對建構函式,原型,例項物件的一些理解

[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指向的原型物件後,例項的內部指標也發生了改變,指向了新的原型物件,然後就能實現類與類之間的繼承了。

天涯猶在,不訴薄涼。