好程式設計師web前端教程分享js閉包

好程式設計師IT發表於2019-04-09

好程式設計師 web 前端教程分享 js 閉包為了更好的理解閉包,從網上搜羅了很多資料,集各家之精華(自認為),拼拼湊湊自己總結了一下。

## 閉包

閉包是一個能讀取其他函式內部變數的函式:

1. 閉包是一個函式

2. 這個函式能讀取到其他函式內部的變數(區域性變數)

3. 他能讓讀取到的變數始終儲存在記憶體中

 

## 閉包的缺陷:

閉包函式讀取到的變數會一直儲存在記憶體中,不做處理地盲目使用很容易有記憶體洩漏(記憶體未釋放或無法釋放所造成的記憶體浪費,導致程式執行速度減慢)的風險

 

## 案例

說了一堆,來點乾貨

這個是從網上看到的一個案例

```

function fun(n,o){

  console.log(o);

  return {

    fun: function(m){

      return fun(m,n);

    }

  };

}

 

var a = fun(0);  // ?

a.fun(1);        // ?        

a.fun(2);        // ?

a.fun(3);        // ?

 

var b = fun(0).fun(1).fun(2).fun(3);  // ?

 

var c = fun(0).fun(1);  // ?

c.fun(2);        // ?

c.fun(3);

```

當時我把程式碼粘過來,邊看程式邊分析,把每一塊分析的過程都寫了下來

```

function fun(n, o) {

    console.log(o);

    return { // 這裡返回一個物件,物件有個 fun 函式

        fun: function (m) { // 函式返回 呼叫 fun 函式的返回值

            return fun(m, n);

        }

    };

}

 

var a = fun(0);  // ? 傳參時只傳了 ,所以 n o undefined a 即為 fun 返回的物件

// a.fun() 就是閉包函式, var a = fun(0) 中的 n=0 o=undefined 都會常駐在記憶體中

a.fun(1);        // ? 重新呼叫 fun(n, 0) m = 1 n = 0 console.log(o) ,結果為

a.fun(2);        // ? 0

a.fun(3);        // ? 0

 

var b = fun(0).fun(1).fun(2).fun(3);  // ?  0 1 2

// 1. fun(0) 為物件,此時的 n = 0 o = undefined ,輸出 undefined

// 2. 然後呼叫物件的 fun(m) m = 1 ,返回值為呼叫外部 fun(n, o) 的返回值, n = 1 o = 0 而這個返回值又是一個物件,輸出

// 3. 然後又呼叫物件的 fun(m) m = 2 ,返回值為呼叫外部 fun(n, o) 的返回值, n = 2 o = 1 而這個返回值又是一個物件,輸出 1

// 4. 然後又呼叫物件的 fun(m) m = 3 ,返回值為呼叫外部 fun(n, o) 的返回值, n = 3 o = 2 而這個返回值又是一個物件,輸出 2

// 這裡指的注意的是每次的 n o 的值都不一樣,是因為他們分別在不同的函式作用域內,這裡每次都呼叫了一個新的 fun() ,開闢了一塊新空間

 

var c = fun(0).fun(1);  // ? undefined

// 而這裡兩次的結果都是 1 ,因為他們都是透過 c 這個物件呼叫的,就是說因為他們都在同一個函式作用域內

c.fun(2);        // ?  1

c.fun(3);        // ?  1

```

分析的過程簡直是一場頭腦風暴,稍不留神就會跑偏,總算寫完之後趕緊去對照他的答案(當時並沒有跑一遍程式),結果發現 `var b = fun(0).fun(1).fun(2).fun(3);` 這裡答案不一樣,他給的答案是 `undefined, 0, 0, 0` ,而我得到的結果是 `undefined, 0, 1, 2` ,我就又回頭看了一遍,覺得自己分析的沒問題啊,這時候突然想到我還沒跑一遍試試,於是抓緊跑一波,結果果然是站在我這邊的。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913892/viewspace-2640758/,如需轉載,請註明出處,否則將追究法律責任。

相關文章