JavaScript Weird Part (38)- 閉包 [1]

閉包 (closures) 是深入了解 JavaScript 不可或缺的概念。在某些函式(function)為一等公民(可來傳遞、當作引數)的程式語言中,閉包(closure)是「一種特殊的函式,會儲存/綁定該詞法作用域(lexical scope)下被引用的變數資訊」,如綁定閉包內被引用的外部變數,讓 closure 可以使用這些變數,這種儲綁定外部變數的行為稱為 capture,被儲存的變數一般稱 captured/free/bound variable。由於這些外部變數被 closure 綁定,因此可以在這些變數宣告的作用域外執行 closure 並使用這些 variables,,所以 closure 廣泛應用於程式區塊間互相傳值/通訊,例如非同步常使用的 callback function,經常會是一個 closure

直接看例子

1
2
3
4
5
6
7
8
9
10
11
12
function doSome() {
var x = 10;
function f(y) {
return x + y;
}
return f;
}
var foo = doSome();

console.log(foo(20)); // 30

console.log(foo(30)); // 40

上面的 f 即為 Closure(閉包),x 稱為 free variable(閒置變數)。閒置變數 x 是指相對於 f 而言,是既非區域變數也非參數的變數,而擁有閒置變數的運算式則稱為 Closure。

對於 f 而言,x 是外部函式變數,而 f 將變數 x 關入自己的範圍,x 在 doSome 執行完畢後,原本應該結束自己的生命週期,但 f 建立了 closure 並傳回,使得 x 能繼續存活。

而如果 f 並沒有捕捉任何變數,例如下面例子:

1
2
3
4
5
6
7
function doSome() {
var x = 10;
function f(y) {
return y + 10;
}
return f;
}

則 f 就只是單純的(一級)函式而已。

其他關於 closure 的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
function doSome() {
var x = 10;
function f(y) {
x = x + y;
return x;
}
return f;
}
var foo = doSome();

console.log(foo(20)); // 30

console.log(foo(30)); // 60
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function doSome() {
var x = 10;
function f(y) {
x = x + y;
return x;
}
return f;
}
var foo1 = doSome();

var foo2 = doSome();

console.log(foo1(20)); // 30

console.log(foo2(20)); // 30

Powered by Hexo and Hexo-theme-hiker

Copyright © 2013 - 2020 CYC'S BLOG All Rights Reserved.

UV : | PV :