1. 程式人生 > >【web前端】JavaScript閉包

【web前端】JavaScript閉包

con 命令式 rate 編程 局部變量 urn 沒有 生命 console

example:

var generateClosure = function(){

  var count = 0;

  var get = function(){

    count++;

    return count;

  };

  return get;

};

var counter = generateClosure();

console.log(counter()); //輸出1

console.log(counter()); //輸出2

console.log(counter()); //輸出3

這段代碼中,generateClosure()函數中有一個局部變量count,初值為0。還有一個叫做get的函數,get將其父作用域,也就是generateClosure()函數中的count變量增加1,並返回count的值。generateClosure()的返回值是get函數。在外部我們通過counter變量調用了generateClosure()函數並獲取了它的返回值,也就是get函數,接下來反復調用幾次counter(),我們發現每次的值都遞增了1。

讓我們看看上面的例子有什麽特點,按照通常命令式編程思維的理解,count是generateClosure()函數內部的變量,它的生命周期就是generateClosure()被調用的時期,當generateClosure()從調用棧中返回時,count變量申請的空間也就被釋放。問題是,在generateClosure()調用結束後,counter()卻引用了“已經釋放了的”count變量,而且非但沒有出錯,反而每次調用counter()時還修改並返回了count。這是怎麽回事呢?

這正是所謂閉包的特性。當一個函數返回它內部定義的一個函數時,就產生了一個閉包,閉包不但包括被返回的函數,還包括這個函數的定義環境。上面例子中,當函數generateClosure()的內部函數get被一個外部變量counter引用時,counter和generateClosure()的局部變量就是一個閉包。

example:

var generateClosure = function{

  var count = 0;

  var get = function(){

    count++;

    return count;

  };

  return get;

};

var counter1 = generateClosure();

var counter2 = generateClosure();

console.log(counter1()); //輸出1

console.log(counter2()); //輸出1

console.log(counter1()); //輸出2

console.log(counter1()); //輸出3

console.log(counter2()); //輸出2

【web前端】JavaScript閉包