理解Javascript_11_constructor實現原理 【轉】

在理解了'對象模型'後,咱們就能夠看一下constructor屬性是如何實現的.html

constructor是什麼函數

簡單的理解,constructor指的就是對象的構造函數。請看以下示例:spa

1
2
3
4
5
6
function Foo(){};
var foo = new Foo();
alert(foo.constructor);//Foo
alert(Foo.constructor);//Function
alert(Object.constructor);//Function
alert(Function.constructor);//Function

對於foo.constructor爲Foo,我想應該很好理解,由於foo的構造函數爲Foo。對於Foo、Object、Function的構造函數爲Function,我想也沒什麼好爭議的。(由於Foo,Object,Function都是函數對象,又由於全部的函數對象都是Function這個函數對象構造出來,因此它們的constructor爲Function,詳細請參考《js_函數對象》)prototype

 

Prototype與Constructor的關係3d

1
2
function Dog(){}
alert(Dog === Dog.prototype.constructor);//true

在 JavaScript 中,每一個函數都有名爲「prototype」的屬性,用於引用原型對象。此原型對象又有名爲「constructor」的屬性,它反過來引用函數自己。這是一種循環引用,如圖:code

 

constructor屬性來自何方htm

咱們來看一下Function構造String的構造過程:對象

 

注:Function構造任何函數對象的過程都是同樣的,因此說無論是String,Boolean,Number等內置對象,仍是用戶自定義對象,其構造過程都和上圖同樣。這裏String只是一個表明而矣!blog

圖中能夠看出constructor是Function在建立函數對象時產生的,也正如'prototype與constructor的關係'中講的那樣,constructor是函數對象prototype鏈中的一個屬性。即String=== String.prototype.constructor。ip

 

我還想用一段代碼來證實一下,理論是正確的:

1
2
3
4
5
6
7
8
9
function Person(){}
var p = new Person();
alert(p.constructor);//Person
alert(Person.prototype.constructor);//Person
alert(Person.prototype.hasOwnProperty('constructor'));//true
 
alert(Person.prototype.isPrototypeOf(p));//true
alert(Object.prototype.isPrototypeOf(p));//true
alert(Person.prototype == Object.prototype);//false

到如今,你會發現這和前面《原型鏈的實現原理》中的默認prototype指向Object.prototype有衝突,顯然當時的理論不是很全面。

 

特別的Object

用心的讀者可能會提出這樣一問題,你這一套理論並不能適用於Object。由於如下的代碼和你上面的理論是衝突的:

 

1
2
alert(Object.prototype.hasOwnProperty('constructor'));//true
alert(Object.prototype.hasOwnProperty('isPrototypeOf'));//true,若是按上面的理論,這裏應該返回false

 

真的是這樣嗎?不是!那咱們來看一下特殊的Object是如何處理的:

你會發現,這圖的原理和上面一張圖的原理是同樣的。這就能正確解釋Object.prototype.hasOwnProperty('isPrototypeOf')爲true!

 

constructor探究

1
2
3
4
5
6
function Animal(){}
 
function Person(){}
 
var person = new Person();
alert(person.constructor); //Person

根據上一節的內容,你能正確的理解這段代碼的結果嗎?思考後,看一下其內存表示:

 

這張圖明確有代表了Function構造Animal和Person的過程。同時也顯示了實例person與Person的關係。

 

再深刻一點,代碼以下:

1
2
3
4
5
6
7
function Animal(){}
function Person(){}
 
Person.prototype = new Animal();
 
var person = new Person();
alert(person.constructor); //Animal

這個時候,person的構造函數成了Animal,怎麼解釋?

 

注:圖中的虛線表示Person默認的prototype指向(只做參考的做用)。可是咱們將Person.prototype指向了new Animal。

此時,Person的prototype指向的是Animal的實例,因此person的constructor爲Animal這個構造函數。

 

結論:constructor的原理很是簡單,就是在對象的原型鏈上尋找constructor屬性。

相關文章
相關標籤/搜索