讀《javascript權威指南> 》第五版 第八章 函數

1. 函數的定義與調用

1、當一個函數在一個對象上被調用時,它的調用所在對象就會成爲函數的一個參數來傳遞
2、函數的return語句:
1. 有return語句,並帶表達式,會終止函數的運行,並返回表達式的值
2. 有return語句,沒有帶表過式,會終止函數的運行,並返回undefined
3. 沒有return語句,沒有帶表過式,自動執行到最後一條語句,並返回undefined
3、函數的參數,js不會檢測函數的參數類型、參數個數,如果比原型更多則自動忽略,更少則會以undefined補上

2.嵌套的函數

1、使用function語句定義的被嵌套函數有可能只在它所嵌入的函數的最頂層定義,不會被嵌入到語句塊中
2、函數直接量,

 var function(x){ return x*x} 
 function face(x){if (x<=1) return  1;else return x*fact(x-1)} 
 var tensquerd =( function(x){return  x*x;})(10)


3、函數命名,現在美元符號和下劃線是除了字母和數字以外,可以用於js的合法標識符。

4、可變長度的參數列表,Arguments對象:
1). arguments 是一個類似數組對象
2). arguments 使我們可以定義一個任意長度的函數。
3).arguments 是一個普通的JS標識符,而不是一個保留字。如果函數有一個參數或者局部變量使用了這個名字,它就會隱藏對Argument對象的引用。
4)、屬性callee 引用正在執行的函數 如:

function(x){
    if(x<=1) return 1;
    else return x*arguments.callee(x-1);
}

3. 作爲數據的函數

1、

function square(x){return x*x;}
var a=square;
c=a(10);//c contains the number 100

a[0]=function(x){return x*x;}

function add(a,b){return a+b;}
function subtract(a,b){return a-b;}
function multiply(a,b){return a*b;}
function divide(a,b){return a/b;}

function operate(operator,operand1,operand2){
    return operator(operand1,operand2);
}

4. 函數屬性

1、length:形參的個數
如:arguments.callee.length;
2、定義自己的屬性

uniqueInteger.counter=0;
function uniqueInteger(){
    return uniqueInteger.counter++;
}


3、apply()和call() o.call(o,1,2) o.apply(o,[1,2])

5. 函數作用域和閉包

準備知識:
即作用域控制着變量與函數的可見性和生命週期
1. 全局作用域(Global Scope)
(1)最外層函數和在最外層函數外面定義的變量擁有全局作用域
(2)所有末定義直接賦值的變量自動聲明爲擁有全局作用域
(3)所有window對象的屬性擁有全局作用域
2. 局部作用域
局部作用域一般只在固定的代碼片段內可訪問到,最常見的例如函數內部 
3. 作用域鏈(Scope Chain)
函數對象和其它對象一樣,擁有可以通過代碼訪問的屬性和一系列僅供JavaScript引擎訪問的內部屬性。其中一個內部屬性是[[Scope]],由ECMA-262標準第三版定義,該內部屬性包含了函數被創建的作用域中對象的集合,這個集合被稱爲函數的作用域鏈,它決定了哪些數據能被函數訪問。
這裏寫圖片描述
4. 運行期上下文(execution context)”
執行此函數時會創建一個稱爲“運行期上下文(execution context)”的內部對象,運行期上下文定義了函數執行時的環境。每個運行期上下文都有自己的作用域鏈,用於標識符解析,當運行期上下文被創建時,而它的作用域鏈初始化爲當前運行函數的[[Scope]]所包含的對象。
這些值按照它們出現在函數中的順序被複制到運行期上下文的作用域鏈中。它們共同組成了一個新的對象,叫“活動對象(activation object)”,該對象包含了函數的所有局部變量、命名參數、參數集合以及this,然後此對象會被推入作用域鏈的前端,當運行期上下文被銷燬,活動對象也隨之銷燬。新的作用域鏈如下圖所示
這裏寫圖片描述
準備知識結束。

1、詞法作用域:在定義它們的作用域裏運行,而不是在執行它們的作用域中運行。注,儘管當一個函數定義了的時候,作用域鏈就固定了,但作用域鏈中定義的屬性還沒有固定。

2、調用對象:activation object (call object ){arguments:Arguments對象,參數,局部變量} 意味着它會隱藏了作用域鏈更上層的同名的屬性。

3、作爲名字空間的調用對象:定義一個只是創建調用對象的函數,這個調用對象充當一個臨時的名字空間,在這個名字空間中定義變量和創建屬性,不會破壞全局的名字空間。代碼如下:
第一種,

function init(){
    //code goes here
    //any variables declared become properties of the call object instead of cluttering up the global namespace.
}
init();

第二種,第一種給全局域加了一個init屬性,第二種更省

function(){
     //code goes herre 
     //any variables declared become properties of the call object instead of cluttering up the global namespace.
 })();


4、作爲閉包的嵌入函數
例子1:

uniqueID=(function(){// The call object of this function holds our   
                     //value
     var i=0;       //this is the private persistent value
     //the outer function returns a nested function that has access
     //to the persistent value;It is this nested function we are //storing in the variable uniqueID above 
    return function(){return i++;}//return and increment
})();//Invoke the outer function after  defining it.

6. Function構造函數

1、Function()構造函數允許js 動態地創建並且運行時編譯。

2、Function()構造函數解析函數體,且每次被調用都創建一個新的函數對象。

3、它所創建的函數並不使用詞法作用域,相反,它總是當作頂層的函數一樣來編譯。

發佈了86 篇原創文章 · 獲贊 6 · 訪問量 36萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章