理解Javascript_11_constructor實(shí)現(xiàn)原理
更新時間:2010年10月18日 00:46:50 作者:
在理解了'對象模型'后,我們就可以看一下constructor屬性是如何實(shí)現(xiàn)的.
constructor是什么
簡單的理解,constructor指的就是對象的構(gòu)造函數(shù)。請看如下示例:
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,我想應(yīng)該很好理解,因為foo的構(gòu)造函數(shù)為Foo。對于Foo、Object、Function的構(gòu)造函數(shù)為Function,我想也沒什么好爭議的。(因為Foo,Object,Function都是函數(shù)對象,又因為所有的函數(shù)對象都是Function這個函數(shù)對象構(gòu)造出來,所以它們的constructor為Function,詳細(xì)請參考《js_函數(shù)對象》)
Prototype與Constructor的關(guān)系
function Dog(){}
alert(Dog === Dog.prototype.constructor);//true
在 JavaScript 中,每個函數(shù)都有名為“prototype”的屬性,用于引用原型對象。此原型對象又有名為“constructor”的屬性,它反過來引用函數(shù)本身。這是一種循環(huán)引用,如圖:

constructor屬性來自何方
我們來看一下Function構(gòu)造String的構(gòu)造過程:

注:Function構(gòu)造任何函數(shù)對象的過程都是一樣的,所以說不管是String,Boolean,Number等內(nèi)置對象,還是用戶自定義對象,其構(gòu)造過程都和上圖一樣。這里String只是一個代表而矣!
圖中可以看出constructor是Function在創(chuàng)建函數(shù)對象時產(chǎn)生的,也正如'prototype與constructor的關(guān)系'中講的那樣,constructor是函數(shù)對象prototype鏈中的一個屬性。即String=== String.prototype.constructor。
我還想用一段代碼來證明一下,理論是正確的:
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
到現(xiàn)在,你會發(fā)現(xiàn)這和前面《原型鏈的實(shí)現(xiàn)原理》中的默認(rèn)prototype指向Object.prototype有沖突,顯然當(dāng)時的理論不是很全面。
特別的Object
用心的讀者可能會提出這樣一問題,你這一套理論并不能適用于Object。因為以下的代碼和你上面的理論是沖突的:
alert(Object.prototype.hasOwnProperty('constructor'));//true
alert(Object.prototype.hasOwnProperty('isPrototypeOf'));//true,如果按上面的理論,這里應(yīng)該返回false
真的是這樣嗎?不是!那我們來看一下特殊的Object是如何處理的:

你會發(fā)現(xiàn),這圖的原理和上面一張圖的原理是一樣的。這就能正確解釋Object.prototype.hasOwnProperty('isPrototypeOf')為true!
constructor探究
function Animal(){}
function Person(){}
var person = new Person();
alert(person.constructor); //Person
根據(jù)上一節(jié)的內(nèi)容,你能正確的理解這段代碼的結(jié)果嗎?思考后,看一下其內(nèi)存表示:

這張圖明確有表明了Function構(gòu)造Animal和Person的過程。同時也顯示了實(shí)例person與Person的關(guān)系。
再深入一點(diǎn),代碼如下:
function Animal(){}
function Person(){}
Person.prototype = new Animal();
var person = new Person();
alert(person.constructor); //Animal
這個時候,person的構(gòu)造函數(shù)成了Animal,怎么解釋?

注:圖中的虛線表示Person默認(rèn)的prototype指向(只作參考的作用)。但是我們將Person.prototype指向了new Animal。
此時,Person的prototype指向的是Animal的實(shí)例,所以person的constructor為Animal這個構(gòu)造函數(shù)。
結(jié)論:constructor的原理非常簡單,就是在對象的原型鏈上尋找constructor屬性。
注:如果你無法正確理解本文內(nèi)容,請回顧前面章節(jié)的內(nèi)容。
簡單的理解,constructor指的就是對象的構(gòu)造函數(shù)。請看如下示例:
復(fù)制代碼 代碼如下:
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,我想應(yīng)該很好理解,因為foo的構(gòu)造函數(shù)為Foo。對于Foo、Object、Function的構(gòu)造函數(shù)為Function,我想也沒什么好爭議的。(因為Foo,Object,Function都是函數(shù)對象,又因為所有的函數(shù)對象都是Function這個函數(shù)對象構(gòu)造出來,所以它們的constructor為Function,詳細(xì)請參考《js_函數(shù)對象》)
Prototype與Constructor的關(guān)系
復(fù)制代碼 代碼如下:
function Dog(){}
alert(Dog === Dog.prototype.constructor);//true
在 JavaScript 中,每個函數(shù)都有名為“prototype”的屬性,用于引用原型對象。此原型對象又有名為“constructor”的屬性,它反過來引用函數(shù)本身。這是一種循環(huán)引用,如圖:

constructor屬性來自何方
我們來看一下Function構(gòu)造String的構(gòu)造過程:

注:Function構(gòu)造任何函數(shù)對象的過程都是一樣的,所以說不管是String,Boolean,Number等內(nèi)置對象,還是用戶自定義對象,其構(gòu)造過程都和上圖一樣。這里String只是一個代表而矣!
圖中可以看出constructor是Function在創(chuàng)建函數(shù)對象時產(chǎn)生的,也正如'prototype與constructor的關(guān)系'中講的那樣,constructor是函數(shù)對象prototype鏈中的一個屬性。即String=== String.prototype.constructor。
我還想用一段代碼來證明一下,理論是正確的:
復(fù)制代碼 代碼如下:
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
到現(xiàn)在,你會發(fā)現(xiàn)這和前面《原型鏈的實(shí)現(xiàn)原理》中的默認(rèn)prototype指向Object.prototype有沖突,顯然當(dāng)時的理論不是很全面。
特別的Object
用心的讀者可能會提出這樣一問題,你這一套理論并不能適用于Object。因為以下的代碼和你上面的理論是沖突的:
復(fù)制代碼 代碼如下:
alert(Object.prototype.hasOwnProperty('constructor'));//true
alert(Object.prototype.hasOwnProperty('isPrototypeOf'));//true,如果按上面的理論,這里應(yīng)該返回false
真的是這樣嗎?不是!那我們來看一下特殊的Object是如何處理的:

你會發(fā)現(xiàn),這圖的原理和上面一張圖的原理是一樣的。這就能正確解釋Object.prototype.hasOwnProperty('isPrototypeOf')為true!
constructor探究
復(fù)制代碼 代碼如下:
function Animal(){}
function Person(){}
var person = new Person();
alert(person.constructor); //Person
根據(jù)上一節(jié)的內(nèi)容,你能正確的理解這段代碼的結(jié)果嗎?思考后,看一下其內(nèi)存表示:

這張圖明確有表明了Function構(gòu)造Animal和Person的過程。同時也顯示了實(shí)例person與Person的關(guān)系。
再深入一點(diǎn),代碼如下:
復(fù)制代碼 代碼如下:
function Animal(){}
function Person(){}
Person.prototype = new Animal();
var person = new Person();
alert(person.constructor); //Animal
這個時候,person的構(gòu)造函數(shù)成了Animal,怎么解釋?

注:圖中的虛線表示Person默認(rèn)的prototype指向(只作參考的作用)。但是我們將Person.prototype指向了new Animal。
此時,Person的prototype指向的是Animal的實(shí)例,所以person的constructor為Animal這個構(gòu)造函數(shù)。
結(jié)論:constructor的原理非常簡單,就是在對象的原型鏈上尋找constructor屬性。
注:如果你無法正確理解本文內(nèi)容,請回顧前面章節(jié)的內(nèi)容。
您可能感興趣的文章:
- js constructor的實(shí)際作用分析
- Javascript的構(gòu)造函數(shù)和constructor屬性
- JavaScript constructor和instanceof,JSOO中的一對歡喜冤家
- 深入分析js中的constructor和prototype
- JavaScript類和繼承 constructor屬性
- JavaScript中幾個重要的屬性(this、constructor、prototype)介紹
- JavaScript中的prototype和constructor簡明總結(jié)
- javascript new后的constructor屬性
- 不用構(gòu)造函數(shù)(Constructor)new關(guān)鍵字也能實(shí)現(xiàn)JavaScript的面向?qū)ο?/a>
- javascript設(shè)計模式Constructor(構(gòu)造器)模式
相關(guān)文章
Javascript動態(tài)創(chuàng)建表格及刪除行列的方法
這篇文章主要介紹了Javascript動態(tài)創(chuàng)建表格及刪除行列的方法,涉及javascript動態(tài)操作表格的相關(guān)技巧,需要的朋友可以參考下2015-05-05JS基于設(shè)計模式中的單例模式(Singleton)實(shí)現(xiàn)封裝對數(shù)據(jù)增刪改查功能
這篇文章主要介紹了JS基于設(shè)計模式中的單例模式(Singleton)實(shí)現(xiàn)封裝對數(shù)據(jù)增刪改查功能.結(jié)合實(shí)例形式分析了javascript基于單例模式結(jié)合ajax針對數(shù)據(jù)庫進(jìn)行增刪改查的相關(guān)操作技巧,需要的朋友可以參考下2018-02-02Javascript實(shí)現(xiàn)基本運(yùn)算器
這篇文章主要為大家詳細(xì)介紹了Javascript實(shí)現(xiàn)基本運(yùn)算器的相關(guān)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07JavaScript數(shù)組去重算法實(shí)例小結(jié)
這篇文章主要介紹了JavaScript數(shù)組去重算法,結(jié)合實(shí)例形式總結(jié)分析了JavaScript數(shù)組去重相關(guān)的讀寫、遍歷、比較、排序等操作及算法改進(jìn)相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2018-05-05基于JavaScript實(shí)現(xiàn)添加到購物車效果附源碼下載
這篇文章主要介紹了基于JavaScript實(shí)現(xiàn)添加到購物車效果附源碼下載的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-08-08