JavaScript——可變范圍和關閉

在JavaScript中,您在使用變量之前先聲明它們:var

> var x;

> x

未定義

> y

ReferenceError:y未定義

您可以使用一個var 語句來聲明和初始化幾個變量:

var x = 1, y = 2, z = 3;

但是我建議每個變量使用一個語句(原因在Syntax中進行了解釋)。因此,我將前面的語句重寫為:

var x = 1;

var y = 2;

var z = 3;

由于提升(請參見變量提升),通常最好在函數的開頭聲明變量。

變量是函數范圍的

變量的范圍始終是完整的功能(與當前塊相反)。例如:

function foo() {

? ? var x = -512;

? ? if (x < 0) {? // (1)

? ? ? ? var tmp = -x;

? ? ? ? ...

? ? }

? ? console.log(tmp);? // 512

}

我們可以看到變量tmp不限于從第(1)行開始的塊。它存在直到函數結束。

變量被吊起

每個變量聲明都是懸掛的:該聲明將移至該函數的開頭,但保留的賦值將保留。例如,請考慮以下函數中第(1)行中的變量聲明:

function foo() {

? ? console.log(tmp); // undefined

? ? if (false) {

? ? ? ? var tmp = 3;? // (1)

? ? }

}

在內部,前面的函數是這樣執行的:

function foo() {

? ? var tmp;? // hoisted declaration

? ? console.log(tmp);

? ? if (false) {

? ? ? ? tmp = 3;? // assignment stays put

? ? }

}

關閉

每個功能 即使它離開了創建它的作用域,它仍然與圍繞它的函數的變量保持聯系。例如:

function createIncrementor(start) {

? ? return function () {? // (1)

? ? ? ? start++;

? ? ? ? return start;

? ? }

}

從第(1)行開始的函數會離開其創建時所在的上下文,但仍保持與以下版本的實時連接start:

> var inc = createIncrementor(5);

> inc()

6

> inc()

7

> inc()

8

一個封閉的功能加上其周邊范圍的變量的連接。因此,createIncrementor()返回的是封閉。

IIFE模式:引入新的范圍

有時您想引入一個新的 變量作用域-例如,防止變量成為全局變量。在JavaScript中,您不能使用塊來這樣做。您必須使用一個函數。但是,存在一種以塊狀方式使用功能的模式。它稱為IIFE(立即調用的函數表達式,發音為“ iffy”):

(function () {? // open IIFE

? ? var tmp = ...;? // not a global variable

}());? // close IIFE

確保完全按照顯示的方式鍵入前面的示例(注釋除外)。IIFE是定義后立即調用的函數表達式。在函數內部,存在新的作用域,以防止其tmp成為全局變量。有關IIFE的詳細信息,請咨詢通過IIFE引入新范圍。

IIFE用例:通過關閉無意間共享

閉包保持它們與外部變量的連接,有時這不是您想要的:

var result = [];

for (var i=0; i < 5; i++) {

? ? result.push(function () { return i });? // (1)

}

console.log(result[1]()); // 5 (not 1)

console.log(result[3]()); // 5 (not 3)

第(1)行中返回的值始終是的當前值i,而不是創建函數時的值。循環完成后,i值為5,這就是數組中所有函數都返回該值的原因。如果希望第(1)行中的函數接收的當前值的快照,則i可以使用IIFE:

for (var i=0; i < 5; i++) {

? ? (function () {

? ? ? ? var i2 = i; // copy current i

? ? ? ? result.push(function () { return i2 });

? ? }());

}

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容