理解Javascript_08_函數(shù)對象
更新時間:2010年10月15日 23:55:31 作者:
如果你無法理解博文在講什么,請回顧前面的系列博文。文章比較深入,如有不對之處,望請指正,謝謝。
函數(shù)對象
首先,大家得明確一個概念:函數(shù)就是對象,代表函數(shù)的對象就是函數(shù)對象。既然是對象,那它又是被誰構(gòu)造出來的呢?下面我們來看一段描述:JavaScript代碼中定義函數(shù),或者調(diào)用Function創(chuàng)建函數(shù)時,最終都會以類似這樣的形式調(diào)用Function函數(shù):var newFun=Function(funArgs, funBody); 。由此可知函數(shù)對象是由Function這個函數(shù)對象構(gòu)造出來的。
注:Function對象本身也是一個函數(shù),因此它也一個函數(shù)對象。關(guān)于Function的深入理解,請見后續(xù)博文。
正面我們來看一段代碼:
//定義方式一
function func(x) {
alert(x);
}
//定義方式二
var func = function(x) {
alert(x);
};
//實(shí)際執(zhí)行
var func = new Function(“x”, “alert(x);”);
通過上面的代碼可知,函數(shù)func無非是由Function對象接收兩個參數(shù)后構(gòu)造出來的而矣!
注:關(guān)于定義方式一與定義方式二的區(qū)別,請見后續(xù)博文
函數(shù)對象的創(chuàng)建過程
函數(shù)對象詳細(xì)創(chuàng)建步驟如下:
1. 創(chuàng)建一個build-in object對象fn
2. 將fn的內(nèi)部[[Prototype]]設(shè)為Function.prototype
3. 設(shè)置內(nèi)部的[[Call]]屬性,它是內(nèi)部實(shí)現(xiàn)的一個方法,處理函數(shù)調(diào)用的邏輯。(簡單的理解為調(diào)用函數(shù)體)
4. 設(shè)置內(nèi)部的[[Construct]]屬性,它是內(nèi)部實(shí)現(xiàn)的一個方法,處理邏輯參考對象創(chuàng)建過程。(簡單的理解為創(chuàng)建對象《理解Javascript_06_理解對象的創(chuàng)建過程》一文)
5. 設(shè)置fn.length為funArgs.length,如果函數(shù)沒有參數(shù),則將fn.length設(shè)置為0
6. 使用new Object()同樣的邏輯創(chuàng)建一個Object對象fnProto
7. 將fnProto.constructor設(shè)為fn
8. 將fn.prototype設(shè)為fnProto
9. 返回fn
步驟1跟步驟6的區(qū)別為,步驟1只是創(chuàng)建內(nèi)部用來實(shí)現(xiàn)Object對象的數(shù)據(jù)結(jié)構(gòu)(build-in object structure),并完成內(nèi)部必要的初始化工作,但它的[[Prototype]]、[[Call]]、[[Construct]]等屬性應(yīng)當(dāng)為 null或者內(nèi)部初始化值,即我們可以理解為不指向任何對象(對[[Prototype]]這樣的屬性而言),或者不包含任何處理(對 [[Call]]、[[Construct]]這樣的方法而言)。步驟6則將按照《理解Javascript_06_理解對象的創(chuàng)建過程》創(chuàng)建一個新的對象,它的 [[Prototype]]等被設(shè)置了。
從上面的處理步驟可以了解,任何時候我們定義一個函數(shù),它的prototype是一個Object實(shí)例,這樣默認(rèn)情況下我們創(chuàng)建自定義函數(shù)的實(shí)例對象時,它們的Prototype鏈將指向Object.prototype。
注:Function一個特殊的地方,是它的[[Call]]和[[Construct]]處理邏輯一樣。深層次的原因?qū)⒃诤罄m(xù)博文中介紹。
下面我們寫一些用例腳本來測試一下上面的理論:
function Animal(){
}
alert(Animal.length);//0
var dog = new Animal();
這個JS證明了步驟5的正確性。最后,還是來看一下函數(shù)對象的內(nèi)存圖,簡單起見,內(nèi)存圖只描述了Animal的構(gòu)造過程:

來自于一個整體的分析圖:

圖片本身已經(jīng)能解釋很多很多的問題了,結(jié)合前面instanceof原理,對象構(gòu)造原理,原型鏈原理,自已去體會吧,我就不多說什么了。
其實(shí)上Function對象是一個很奇妙的對象,它與Object的關(guān)系更是撲朔迷離,我將在《理解Javascript_09_Function與Object》中解釋這一切。
最后的聲明:理論過于復(fù)雜,我不改保證其正確性。但經(jīng)過多方的測試,還未發(fā)現(xiàn)理論與實(shí)際沖突的地方。
首先,大家得明確一個概念:函數(shù)就是對象,代表函數(shù)的對象就是函數(shù)對象。既然是對象,那它又是被誰構(gòu)造出來的呢?下面我們來看一段描述:JavaScript代碼中定義函數(shù),或者調(diào)用Function創(chuàng)建函數(shù)時,最終都會以類似這樣的形式調(diào)用Function函數(shù):var newFun=Function(funArgs, funBody); 。由此可知函數(shù)對象是由Function這個函數(shù)對象構(gòu)造出來的。
注:Function對象本身也是一個函數(shù),因此它也一個函數(shù)對象。關(guān)于Function的深入理解,請見后續(xù)博文。
正面我們來看一段代碼:
復(fù)制代碼 代碼如下:
//定義方式一
function func(x) {
alert(x);
}
//定義方式二
var func = function(x) {
alert(x);
};
//實(shí)際執(zhí)行
var func = new Function(“x”, “alert(x);”);
通過上面的代碼可知,函數(shù)func無非是由Function對象接收兩個參數(shù)后構(gòu)造出來的而矣!
注:關(guān)于定義方式一與定義方式二的區(qū)別,請見后續(xù)博文
函數(shù)對象的創(chuàng)建過程
函數(shù)對象詳細(xì)創(chuàng)建步驟如下:
1. 創(chuàng)建一個build-in object對象fn
2. 將fn的內(nèi)部[[Prototype]]設(shè)為Function.prototype
3. 設(shè)置內(nèi)部的[[Call]]屬性,它是內(nèi)部實(shí)現(xiàn)的一個方法,處理函數(shù)調(diào)用的邏輯。(簡單的理解為調(diào)用函數(shù)體)
4. 設(shè)置內(nèi)部的[[Construct]]屬性,它是內(nèi)部實(shí)現(xiàn)的一個方法,處理邏輯參考對象創(chuàng)建過程。(簡單的理解為創(chuàng)建對象《理解Javascript_06_理解對象的創(chuàng)建過程》一文)
5. 設(shè)置fn.length為funArgs.length,如果函數(shù)沒有參數(shù),則將fn.length設(shè)置為0
6. 使用new Object()同樣的邏輯創(chuàng)建一個Object對象fnProto
7. 將fnProto.constructor設(shè)為fn
8. 將fn.prototype設(shè)為fnProto
9. 返回fn
步驟1跟步驟6的區(qū)別為,步驟1只是創(chuàng)建內(nèi)部用來實(shí)現(xiàn)Object對象的數(shù)據(jù)結(jié)構(gòu)(build-in object structure),并完成內(nèi)部必要的初始化工作,但它的[[Prototype]]、[[Call]]、[[Construct]]等屬性應(yīng)當(dāng)為 null或者內(nèi)部初始化值,即我們可以理解為不指向任何對象(對[[Prototype]]這樣的屬性而言),或者不包含任何處理(對 [[Call]]、[[Construct]]這樣的方法而言)。步驟6則將按照《理解Javascript_06_理解對象的創(chuàng)建過程》創(chuàng)建一個新的對象,它的 [[Prototype]]等被設(shè)置了。
從上面的處理步驟可以了解,任何時候我們定義一個函數(shù),它的prototype是一個Object實(shí)例,這樣默認(rèn)情況下我們創(chuàng)建自定義函數(shù)的實(shí)例對象時,它們的Prototype鏈將指向Object.prototype。
注:Function一個特殊的地方,是它的[[Call]]和[[Construct]]處理邏輯一樣。深層次的原因?qū)⒃诤罄m(xù)博文中介紹。
下面我們寫一些用例腳本來測試一下上面的理論:
復(fù)制代碼 代碼如下:
function Animal(){
}
alert(Animal.length);//0
var dog = new Animal();
這個JS證明了步驟5的正確性。最后,還是來看一下函數(shù)對象的內(nèi)存圖,簡單起見,內(nèi)存圖只描述了Animal的構(gòu)造過程:

來自于一個整體的分析圖:

圖片本身已經(jīng)能解釋很多很多的問題了,結(jié)合前面instanceof原理,對象構(gòu)造原理,原型鏈原理,自已去體會吧,我就不多說什么了。
其實(shí)上Function對象是一個很奇妙的對象,它與Object的關(guān)系更是撲朔迷離,我將在《理解Javascript_09_Function與Object》中解釋這一切。
最后的聲明:理論過于復(fù)雜,我不改保證其正確性。但經(jīng)過多方的測試,還未發(fā)現(xiàn)理論與實(shí)際沖突的地方。
您可能感興趣的文章:
- 理解Javascript_15_作用域分配與變量訪問規(guī)則,再送個閉包
- 理解Javascript_14_函數(shù)形式參數(shù)與arguments
- 理解Javascript_13_執(zhí)行模型詳解
- 理解Javascript_12_執(zhí)行模型淺析
- 理解Javascript_11_constructor實(shí)現(xiàn)原理
- 理解Javascript_10_對象模型
- 理解Javascript_09_Function與Object
- 理解Javascript_07_理解instanceof實(shí)現(xiàn)原理
- 理解Javascript_06_理解對象的創(chuàng)建過程
- 理解Javascript_05_原型繼承原理
- 理解Javascript_03_javascript全局觀
- 理解Javascript_02_理解undefined和null
- 理解Javascript_01_理解內(nèi)存分配原理分析
相關(guān)文章
微信小程序開發(fā)之組件設(shè)計(jì)規(guī)范
這篇文章主要給大家介紹了關(guān)于微信小程序開發(fā)之組件設(shè)計(jì)規(guī)范的相關(guān)資料,對剛?cè)腴T學(xué)習(xí)微信小程序的同學(xué)們還是挺有幫助的,需要的朋友可以參考下2021-05-05js實(shí)現(xiàn)簡單省市區(qū)三級選擇聯(lián)級
這篇文章主要介紹了js實(shí)現(xiàn)簡單省市區(qū)三級選擇聯(lián)級,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-04-04JavaScript設(shè)計(jì)模型Iterator實(shí)例解析
這篇文章主要介紹了JavaScript設(shè)計(jì)模型Iterator實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-01-01關(guān)于TypeScript應(yīng)該盡量避免的語法總結(jié)
TypeScript是JavaScript的超集,具有類型系統(tǒng),支持ES6語法,支持面向?qū)ο缶幊痰母拍?下面這篇文章主要給大家介紹了關(guān)于TypeScript應(yīng)該盡量避免的語法,需要的朋友可以參考下2022-04-04小程序開發(fā)實(shí)戰(zhàn)指南之封裝自定義彈窗組件
最近在做公司的小程序項(xiàng)目,發(fā)現(xiàn)設(shè)計(jì)上有很多不統(tǒng)一,代碼上有很多冗余,下面這篇文章主要給大家介紹了關(guān)于小程序開發(fā)實(shí)戰(zhàn)指南之封裝自定義彈窗組件的相關(guān)資料,需要的朋友可以參考下2022-11-11JavaScript實(shí)現(xiàn)的簡單冪函數(shù)實(shí)例
這篇文章主要介紹了JavaScript實(shí)現(xiàn)的簡單冪函數(shù),實(shí)例分析了javascript實(shí)現(xiàn)冪運(yùn)算的技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-04-04