js 函數的閉包


 

 

閉包

閉包

任何的書,講閉包,一定是下面的經典案例:

1  function outer(){

2  var a = 333;

3  function inner(){

4  console.log(a);

5  }

6  return inner;

7  }

9  var inn = outer();

10  inn(); //彈出333

 

推導過程:

我們之前已經學習過,inner()這個函數不能在outer外面調用,因為outer外面沒有inner的定義:

1  function outer(){

2  var a = 888;

3  function inner(){

4  console.log(a);

5  }

6  }

//在全局調用inner但是全局沒有inner的定義,所以報錯

8  inner();

但是我們現在就想在全局作用域下,運行outer內部的inner,此時我們必須想一些奇奇怪怪的方法。

 

有一個簡單可行的辦法,就是讓outer自己returninner

1  function outer(){

2  var a = 333;

3  function inner(){

4  console.log(a);

5  }

return inner; //outer返回了inner的引用

7  }

9  var inn = outer(); //inn就是inner函數了

10  inn(); //執行inn,全局作用域下沒有a的定義

11  //但是函數閉包,能夠把定義函數的時候的作用域一起記憶住

12  //能夠輸出333

這就說明了,inner函數能夠持久保存自己定義時的所處環境,並且即使自己在其他的環境被調用的時候,依然可以訪問自己定義時所處環境的值。

 


一個函數可以把它自己內部的語句,和自己聲明時所處的作用域一起封裝成了一個密閉環境,我們稱為閉包Closures)。

 

每個函數都是閉包,每個函數天生都能夠記憶自己定義時所處的作用域環境。但是,我們必須將這個函數,挪到別的作用域,才能更好的觀察閉包。這樣才能實驗它有沒有把作用域給“記住”。 

我們發現,把一個函數從它定義的那個作用域,挪走,運行。嘿,這個函數居然能夠記憶住定義時的那個作用域不管函數走到哪里,定義時的作用域就帶到了哪里。這就是閉包。

 

閉包在工作中是一個用來防止產生隱患的事情,而不是加以利用的性質。

因為我們總喜歡在函數定義的環境中運行函數。從來不會把函數往外挪。那為啥學習閉包,防止一些隱患,面試絕對考。

 

閉包的性質

每次重新引用函數的時候,閉包是全新的。

1  function outer(){

2  var count = 0;

3  function inner(){

4  count++;

5  console.log(count);

6  }

7  return inner;

8  }

10  var inn1 = outer();

11  var inn2 = outer();

12 

13  inn1(); //1

14  inn1(); //2

15  inn1(); //3

16  inn1(); //4

17  inn2(); //1

18  inn2(); //2

19  inn1(); //5

 

無論它在何處被調用,它總是能訪問它定義時所處作用域中的全部變量

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM