1.函數
//函數聲明
function f1(){}
//函數表達式
var f1=function(){}
這兩者的區別在於:函數聲明會在所有代碼執行前進行解析,而函數表達式和聲明變量一樣都是執行到這裏的時候才進行解析。(看例子)f1()
var f1=function(){
console.log(1)
}
Uncaught TypeError: f1 is not a function(…)
f1()//輸出結果1
function f1(){
console.log(1)
}
2.閉包
//例子1
var f1=function(){
var a=0;
return function(){
return a++;
}
}()
console.log(f1()) //輸出0
console.log(f1()) //輸出1
上面函數就是一個簡單的閉包。 (再看一個例子)//例子2
var f1=function(){
var a=0;
return function(){
return a++;
}
}
console.log(f1()()) //輸出0
console.log(f1()()) //輸出0
咦,是不有有點奇怪,看起來相同的兩個例子會輸出不同的結果?(讓我們再看兩個例子)</pre><pre name="code" class="javascript">//例子3
var f1=function(){
var a=0;
console.log(123)
return function(){
return a++;
}
}()
console.log(f1())
console.log(f1())
//打印 123 0 1
</pre><pre name="code" class="javascript">
//例子4
var f1=function(){
var a=0;
console.log(123)
return function(){
return a++;
}
}
console.log(f1()())
console.log(f1()())
//打印 123 0 123 0
我們來解析一下:這兩個例子中,例子3 因爲在聲明函數f1的時候已經自己執行了一次,所以我們可以把例子3看成:
</pre><pre name="code" class="javascript">var f1=function(){
return a++;
}
//因爲自動執行了一次,所以打印123 a是能訪問外面的a, a此時爲0
console.log(f1()) //打印 0
//調用的時候並沒有打印 123,所以也沒執行 var a=0; 此時 a=1
console.log(f1()) //打印 1
//我們可以看出 a一直存在局部變量中,並沒有被回收
/*爲什麼沒被回收呢?因爲父函數在執行後子函數被賦給了一個全局變量,
而子函數是依附父函數的,所以就算之後沒執行父函數,父函數也會存在內存中,
不會被回收
*/
</pre><pre>
怎麼樣,是不是知道這兩個例子爲什麼打印的東西不一樣了吧!!!!!是不是對閉包有點理解了~~