JS中的 閉包(Closure)

什麼是閉包?javascript

閉包就是可以讀取其餘函數內部變量的函數。java

例如在javascript中,只有函數內部的子函數才能讀取局部變量,因此閉包能夠理解成「定義在一個函數內部的函數「。
在本質上,閉包是將函數內部和函數外部鏈接起來的橋樑。數組

代碼演示:bash

function裏嵌套function時,內部的function能夠訪問外部function裏的變量閉包

function fn(x) {
  var tmp = 3;
  function bar(y) {
    alert(x + y + (++tmp));
  }
  bar(2);
}
fn(1)
複製代碼

無論執行多少次,都會alert 7,由於bar能訪問fn的參數x,也能訪問fn的變量tmp函數

可是,這並 不是 不是 不是 閉包ui

當你return的是內部function時,纔是閉包spa

內部functionclose-over外部function的變量直到內部function結束。code

function fn(x) {
  var tmp = 3;
  return function (y) {
    alert(x + y + (++tmp));
  }
}
var bar = fn(1); // bar 如今是一個閉包
bar(2);
複製代碼

上面的腳本最終也會輸出alert 7,由於雖然bar不直接處於fn的內部做用域,但bar仍是能訪問xtmp生命週期

可是,因爲tmp仍存在與bar閉包的內部,因此它仍是會自加1,並且你每次調用bar時它都會自加1。

其實,咱們其實能夠創建不止一個閉包方法,好比return它們的數組,也能夠把它們設置爲全局變量。它們全都指向相同的x和相同的tmp,而不是各自有一份副本。

一個須要關注的點:

JS裏處理object時是用到引用傳遞的,那麼,你調用fn時傳遞一個objectfn函數return的閉包也會引用最初那個object

function fn(x) {
  var tmp = 3;
  return function (y) {
    alert(x + y + tmp);
    x.memb = x.memb ? x.memb + 1 : 1;
    alert(x.memb);
  }
}
var tar = new Number(1);
var bar = fn(tar); // bar 如今是一個引用了tar的閉包
bar(2);
複製代碼

不出咱們意料,每次運行bar(2)x.memb都會自加1。但須要注意的是x每次都指向同一個object變量tar

這樣內存泄漏有關。

有一個不用return關鍵字的閉包例子:

function closureExample(obj, text, timedelay) { 
    setTimeout(function() { 
        document.getElementById(objID).innerHTML = text; 
        }, timedelay); 
} 
closureExample(‘myDiv’, ‘Closure is created’, 500); 
複製代碼

總結:

JS裏的function能訪問它們的:

  • 參數
  • 局部變量或函數
  • 外部變量

若是在一個函數中,又嵌套了一個函數,而且裏面這個函數引用外面的函數的變量,那麼就是閉包。

閉包的特色:

  • 閉包能夠產生內存泄露
  • 閉包能夠延長變量的生命週期

~_~

相關文章
相關標籤/搜索