還是先從乙個題目開始:
寫乙個隔1s輸出陣列的一項的函式。如果可以用es6語法,則可以這麼寫:
function print (arr) , 1000 * i);
}}
但是如果把這裡的let
改成var
,則輸出就會變成一連串的undefined
。
有同學很快想到了這是閉包啊,因為settimeout
把函式加入到microqueue
中,所以等到settimeout的函式體執行時,i
已經走完了for
迴圈,變成了arr.length
。arr[arr.length]
顯然是undefined。
簡單修改一下,變成es5的語法。
function print (arr) , 1000 * index);
})(i);
}}
其實就是利用閉包是向父級作用域尋找值的特性,給i
包裝一層作用域,把i
存起來。
閉包概念還請翻看之前的一篇blog-閉包和類。
到這裡閉包的理解應該差不多了,而今天的關鍵點在於——
阮一峰老師的《ecmascript 6》入門裡給出[定義](
es6 新增了他提到了let的幾個特性:let
命令,用來宣告變數。它的用法類似於var
,但是所宣告的變數,只在let
命令所在的**塊內有效。
只存在於塊級作用域中
不存在變數提公升
暫時性死區
不允許重複宣告
我更感興趣的是,在es5的語法中,如何模擬let
這種塊級作用域的效果。這個時候,應該讓babel
出場了。
"use strict";
function print(arr) , 1000 * i);
};for (var i = 0; i < arr.length; i++)
}
其實可以對比發現,babel
轉換後的**和我們上面寫的es5實現其實是一樣的。
大概就是通過對let
繫結的塊級作用域加乙個函式,把let
宣告的引數,通過函式傳入,達到塊級作用域的效果。
大家可以在babel
試一下let
的其他特性,轉移出的es5語法並不能實現有的特性,比如暫時性死區。
完,感謝閱讀。
面試小題 閉包模擬塊級作用域
已知陣列 a b c d e 編寫 每過 1 秒列印一下陣列中的值。var arr a b c d e for var i 0 i arr.length i 1000 i 1 i 複製 利用 es6 中 let 塊級作用域的特性。var arr a b c d e for let i 0 i arr...
作用域和閉包
給執行上下文環境下乙個通俗的定義 在執行 之前,把將要用到的所有的變數都事先拿出來,有的直接賦值了,有的先用undefined占個空。全域性 的上下文環境資料內容為 1 普通變數 包括函式表示式,如 var a 10 宣告 預設賦值為undefined 2 函式宣告 如 function fn 賦值...
作用域和閉包
題目 知識點 1 執行上下文 2 this 3 作用域 4 作用域鏈 5 閉包 一 執行上下文 ps 函式宣告和函式表示式的區別 執行上下文 console.log a undefined var a 10 fn 張三 22 張三 22 function fn name 在script標籤內的全域性...