DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> 理解Javascript_08_函數對象
理解Javascript_08_函數對象
編輯:關於JavaScript     
函數對象
首先,大家得明確一個概念:函數就是對象,代表函數的對象就是函數對象。既然是對象,那它又是被誰構造出來的呢?下面我們來看一段描述:JavaScript代碼中定義函數,或者調用Function創建函數時,最終都會以類似這樣的形式調用Function函數:var newFun=Function(funArgs, funBody); 。由此可知函數對象是由Function這個函數對象構造出來的。
注:Function對象本身也是一個函數,因此它也一個函數對象。關於Function的深入理解,請見後續博文。
正面我們來看一段代碼:
復制代碼 代碼如下:
//定義方式一
function func(x) {
alert(x);
}
//定義方式二
var func = function(x) {
alert(x);
};
//實際執行
var func = new Function(“x”, “alert(x);”);

通過上面的代碼可知,函數func無非是由Function對象接收兩個參數後構造出來的而矣!

注:關於定義方式一與定義方式二的區別,請見後續博文



函數對象的創建過程

函數對象詳細創建步驟如下:

1. 創建一個build-in object對象fn

2. 將fn的內部[[Prototype]]設為Function.prototype
3. 設置內部的[[Call]]屬性,它是內部實現的一個方法,處理函數調用的邏輯。(簡單的理解為調用函數體)

4. 設置內部的[[Construct]]屬性,它是內部實現的一個方法,處理邏輯參考對象創建過程。(簡單的理解為創建對象《理解Javascript_06_理解對象的創建過程》一文)

5. 設置fn.length為funArgs.length,如果函數沒有參數,則將fn.length設置為0
6. 使用new Object()同樣的邏輯創建一個Object對象fnProto
7. 將fnProto.constructor設為fn
8. 將fn.prototype設為fnProto
9. 返回fn

步驟1跟步驟6的區別為,步驟1只是創建內部用來實現Object對象的數據結構(build-in object structure),並完成內部必要的初始化工作,但它的[[Prototype]]、[[Call]]、[[Construct]]等屬性應當為 null或者內部初始化值,即我們可以理解為不指向任何對象(對[[Prototype]]這樣的屬性而言),或者不包含任何處理(對 [[Call]]、[[Construct]]這樣的方法而言)。步驟6則將按照《理解Javascript_06_理解對象的創建過程》創建一個新的對象,它的 [[Prototype]]等被設置了。
從上面的處理步驟可以了解,任何時候我們定義一個函數,它的prototype是一個Object實例,這樣默認情況下我們創建自定義函數的實例對象時,它們的Prototype鏈將指向Object.prototype。

注:Function一個特殊的地方,是它的[[Call]]和[[Construct]]處理邏輯一樣。深層次的原因將在後續博文中介紹。

下面我們寫一些用例腳本來測試一下上面的理論:

復制代碼 代碼如下:
function Animal(){
}
alert(Animal.length);//0

var dog = new Animal();

這個JS證明了步驟5的正確性。最後,還是來看一下函數對象的內存圖,簡單起見,內存圖只描述了Animal的構造過程:

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

圖片本身已經能解釋很多很多的問題了,結合前面instanceof原理,對象構造原理,原型鏈原理,自已去體會吧,我就不多說什麼了。

其實上Function對象是一個很奇妙的對象,它與Object的關系更是撲朔迷離,我將在《理解Javascript_09_Function與Object》中解釋這一切。


最後的聲明:理論過於復雜,我不改保證其正確性。但經過多方的測試,還未發現理論與實際沖突的地方。
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved