函數表達式是JavaScript中的一個既強大又容易使人困惑的特性。閉包
1.函數聲明app
function functionName(arg0,arg1,arg2){
//函數體
}
複製代碼
先有function關鍵字,而後是函數的名字,就是指定函數名的方式。他還有一個重要特徵就是函數聲明提高意思是在執行代碼以前會先讀取函數聲明。(意味能夠將函數聲明放在調用它的語句後面)以下:函數
sayHi()
function sayHi(){
alert("Hi!");
}
複製代碼
2.函數表達式ui
函數表達式有幾種不一樣的語法形式,下面是最多見的一種。this
var functionName=function(arg0,arg1,arg2){
//函數體
}
複製代碼
建立一個函數並將它賦值給變量functionName,建立的函數叫作匿名函數,由於function關鍵字後面沒有標識符。(匿名函數也叫作拉姆達函數) 匿名函數的name屬性是空字符串。spa
遞歸函數是在一個函數經過名字調用自身的狀況下構成的以下:指針
function factorial(num){
if(num<=1){
return 1;
}else{
return num*factorial(num-1);
}
}
複製代碼
1.arguments.callee是一個指向正在執行的函數的指針,所以能夠用來實現對 函數的遞歸調用以下:code
function factorial(num){
if(num<=1){
return 1;
}else{
return num*arguments.callee(num-1);
}
}
複製代碼
用arguments.callee代替函數名,能夠確保不管怎樣調用函數都不會出問題。可是在嚴格模式下訪問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等於window,而當函數做爲某個對象的方法調用時,this等於那個對象。不過匿名函數的執行環境具備全局性,所以其this對象一般指向window
若是在經過call()或apply()改變函數執行環境的狀況下,this就會指向其它對象。