閉包是指有權訪問另外一個函數做用域中的變量的函數。建立閉包的常見方式,就是在一個函數內部建立另外一個函數。閉包
常見閉包出現的問題函數
function createFunction(){ var result = new Array(); for(var i=0; i<10; i++){ result[i] = function(){ return i; } } console.log('i 的值:'+ i) return result; }
createFunction() 返回的結果 spa
當咱們調用 createFunction()[1]();時返回的是code
事實上arr的每一項調用的結果都是10圖片
爲何呢?作用域
事實上你在調用每一項時,實際上是這樣的it
function childFunction(){ var i = 10; return function(){ return i; } }
這個 i 來自它的父級做用域io
或者咱們這麼說,return i; 中的 i 跟 for循環中的 i 實際上是不同的。由於此時的 console
函數並無調用,而當你調用的時候,它纔去做用域鏈搜索 i 的值。而此時 i = 10;for循環
咱們嘗試在返回以前更改 i =9999;
獲得證實。
那麼要怎樣才能讓它返回咱們預期的那樣呢?
咱們只要把 result [i] 中的 i 當作參數傳進函數
result[i] = (function(num){ return function(){ return num; } })(i)
這一段代碼到底發生了什麼?咱們讓 外層 的函數傳入參數並當即執行,此時裏面的 num 等於傳入的參數, 等到最內層函數調用的時候,它會拿到外層的num。
最後,不少人覺得閉包指的是一個函數被一個函數返回,其實不是。它指的是 有權訪問另外一個函數做用域中的變量的函數,跟是否是被 返不返回並無關係。咱們通常讓其返回一個函數,是但願這個閉包能按照咱們的預期進行。