js實例化以及constructor探究

js實例化以及constructor探究

先來一個構造函數:

function Person(name){
    this.name=name;
}

對其添加原型鏈:

Person.prototype={
getName:function(){

    return this.name;

}
}

對其實例化:

var person=new Person('xiaopu');

這樣完成一個基本的構造函數加原型鏈的組合封裝。

我們不去探究原型鏈的過程 這個可以參考前邊的文章

我們來主要研究一下實例化過程,以及實例化前後constructor的指向問題:

實例化過程:

實例化其實是一個new的過程,在這裏將其分爲四步去執行

1.實例一個object對象

2.將構造函數的作用域置入該object

3.將構造函數賦值到object

4.執行object代碼

在這個過程中 首先是實例化一個object,所以新的實例person實際是通過Object繼承而來的。

也就是說person instanceof Object==person instanceof Person==true

constructor指向:

每個構造函數都有一個prototype屬性,這個屬性指針指向的是一個object,

每個對象都有一個constructor指針,這個指針指向的是創建該對象實例的構造函數。

當然函數也是對象也會有constructor屬性例如Person.constructor就指向了Function,因爲Function是它的構造函數,也就是說Person是Function的實例。

1.

上面代碼我們重寫如下:

function Person(name){

this.name=name;

}

var person=new Person('xiapu');

此時Person.prototype是一個空對象,

而person.constructor指向的是Person,Person.prototype.constructor指向的也是Person

2.

當我們顯示的對構造函數進行原型擴展後

Person.prototype={
getName:function(){return this.name}

}

這個時候person.constructor以及Person.prototype.constructor都指向的是Object而不是Person

究其原因,是因爲一個新對象賦值給了Person.prototype,此時的Person.prototype是一個object的實例。

這個object的constructor指向的肯定就是object的構造函數類Object,所以二者的constructor都會指向Object

如果constructor對於你的判斷很重要 可以在原型中添加constructor並將其賦值爲Person

Person.prototype={
constructor:Person,

getName:function(){return this.name}
}

3.

而如果以Person.prototype.getName=function(){return this.name}去定義原型對象,

此時的constructor就不存在新建一個object過程,那麼二者的指向依然會是Person

但是如果一開始用對象方式聲明prototype然後又用原型鏈去聲明原型屬性 那麼此時二者的constructor依然指向的是Object,因爲對象方式聲明的prototype已經覆蓋了原先構造函數中存在的原型鏈。

即:Person.prototype={};

Person.prototype.getName=function(){return this.name}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章