(javascript)淺析js函數表達式和函數聲明以及閉包

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>

怎麼樣,是不是知道這兩個例子爲什麼打印的東西不一樣了吧!!!!!是不是對閉包有點理解了~~



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章