函數表達式
函數表達式是JavaScript中的一個既強大又容易令人困惑的特性。
定義函數表達式的方法
1.函數聲明
function functionName(arg0,arg1,arg2){
//函數體
}
先有function關鍵字,然後是函數的名字,就是指定函數名的方式。他還有一個重要特徵就是<font color="red">函數聲明提升</font>意思是在執行代碼之前會先讀取函數聲明。(意味可以將函數聲明放在調用它的語句後面)如下:
sayHi()
function sayHi(){
alert("Hi!");
}
2.函數表達式
函數表達式有幾種不同的語法形式,下面是最常見的一種。
var functionName=function(arg0,arg1,arg2){
//函數體
}
創建一個函數並將它賦值給變量functionName,創建的函數叫做<font color="red">匿名函數</font>,因爲function關鍵字後面沒有標識符。(匿名函數也叫做<font color="red">拉姆達函數</font>) 匿名函數的name屬性是空字符串。
遞歸
遞歸函數是在一個函數通過名字調用自身的情況下構成的如下:
function factorial(num){
if(num<=1){
return 1;
}else{
return num*factorial(num-1);
}
}
1.arguments.callee是一個指向正在執行的函數的指針,因此可以用來實現對
函數的<font color="red">遞歸調用</font>如下:
function factorial(num){
if(num<=1){
return 1;
}else{
return num*arguments.callee(num-1);
}
}
用arguments.callee代替函數名,可以確保無論怎樣調用函數都不會出問題。但是在<font color="red">嚴格模式</font>下訪問arguments.callee屬性會出錯。可以使用命名函數表達式來達到相同的結果。如下:
var factorial=(function f(num){
if(num<=1){
return 1;
}else{
return num*f(num-1);
}
}
這種方式在嚴格模式和非嚴格模式都可以使用。
閉包
閉包是指有權訪問另一個函數作用域的變量的函數,創建閉包的常見方式,就是在一個函數內部創建另一個函數。如下:
function init(){
var name="Mike";
function displayName(){
alert(name);
}
displayName();
}
init()
init()函數創建了一個局部變量name和一個名爲displayName()的函數。displayName()函數是定義在init()裏面的內部函數,僅在該函數體內使用。
displayName()沒有自己的局部變量,然而它可以訪問到外部函數的變量,所以displayName()可以使用父函數init()中聲明的變量name。
注意:由於閉包會攜帶它的函數作用域,因此會比其它函數佔用更多內存。過度使用閉包可能會導致內存佔用過多。
this
在全局函數中,this等於window,而當函數作爲某個對象的方法調用時,this等於那個對象。不過匿名函數的執行環境具有全局性,因此其this對象通常指向window
如果在通過call()或apply()改變函數執行環境的情況下,this就會指向其它對象。