函數表達式
1、JavaScript中定義函數有2鐘方法:
1-1.函數聲明:
1-2.函數表達式:
if(condition){
function sayHi(){
alert("Hi!");
}
} else {
function sayHi(){
alert("Yo!");
}
}
var sayHi;
if(condition){
sayHi = function(){
alert("Hi!");
}
} else {
sayHi = function(){
alert("Yo!");
}
}
function factorial(num){
if (num <= 1){
return 1;
} else {
return num * arguments.callee(num-1);
}
}
var anotherFactorial = factorial;
factorial = null;
alert(anotherFactorial(4)); //24
var factorial = function f(num){
if (num <= 1){
return 1;
} else {
return num * f(num-1);
}
}
指有權訪問另一個函數作用域中的變量的函數。(常見形式為函數嵌套)
4-1.執行環境 及 作用域
執行環境execution context簡稱環境,定義了變量和函數有權訪問的其他數據,并決定他們的各自行為。
?、倜總€執行環境都有一個變量對象variable object,保存環境定義的所有變量和函數。該對象無法編碼訪問,但解析器在處理數據時會在后臺使用它。
全局變量對象是最外圍的一個執行環境。在Web瀏覽器中被認為是window對象,故所有全局對象和函數都是window對象的屬性和方法創建的。
執行環境中的代碼執行完后,該環境就被銷毀,保存其中的變量和函數定義也隨之銷毀。
②代碼在環境中執行時,會創建變量對象的一個作用域鏈scope chain,用于保證對執行環境有權訪問的所有變量和函數的有序訪問。
作用域鏈前端,始終是當前執行的代碼所在環境的變量對象。當該環境為函數時,會將活動對象作為變量對象。
活動對象最開始只包含一個變量,即argumnt對象。
作用域鏈中的下一個變量對象來自包含環境,而下一個變量對象來自下一個包含環境,直至延續到全局執行環境。
③標識符解析:從前段開始,沿著作用域鏈一級一級地搜索標識符的過程。【找不到通常會導致錯誤發生】
4-2.函數創建、執行時:
4-3.閉包的作用域鏈
在另外一個函數內部定義的函數會將包含函數的活動對象添加到它的作用域鏈中。
①將函數對象賦值null,等于通知垃圾回收例程將其清除,隨著函數作用域鏈被銷毀,其作用域鏈(不除了全局作用域)也會被安全銷毀。
②由于閉包會攜帶包含函數的作用域,所以會比其他函數占用更多內存。
4-4.閉包與變量
作用域鏈的一個副作用:閉包只能取得包含函數中任何變量的最后一個值。
4-5.this對象
this對象是在運行時基于函數的執行環境綁定的。
在全局函數中,this等于window;當函數被某對象調用時,this為該對象。
匿名函數的執行環境有全局性,其this對象通常指window。通過call()或spply()改變函數執行環境時,this指向其對象。
?、倜總€函數在被調用時,都會自動取得兩個特殊變量:this和argument。內部函數在搜索這兩個變量時,只會搜索到期活動對象為止,永遠不可能訪問外部函數的這兩個變量。
不過將外部作用域的this對象保存在一個閉包能訪問的變量里,就可讓閉包訪問該對象。
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};
alert(object.getNameFunc()()); //"MyObject"
5、函數聲明 轉換為 函數表達式
JavaScript將function關鍵字昨晚函數聲明的開始,但函數聲明后面不能跟圓括號,所以function(){......}();會出錯。
要將函數聲明轉換為函數表達式,需為函數聲明加一對圓括號:
新聞熱點
疑難解答