1. 程式人生 > >由es6 let想到的塊級作用域問題-面試題

由es6 let想到的塊級作用域問題-面試題

面試題情景:

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10
a[7](); // 10
a[8](); // 10
a[9](); // 10

這裡好像和想的不那麼一樣,但是js就是這樣,i就是全域性變數,所以用來計數的迴圈變數洩露為全域性變數。上面程式碼中,變數i是var宣告的,在全域性範圍內都有效。所以每一次迴圈,新的i值都會覆蓋舊值,導致最後輸出的是最後一輪的i的值。也可以這樣來講,迴圈的時候i是沒有賦值的,所以a中的值就是function () {console.log(i);};,最終i等於10,所以每次呼叫輸出的都是10.

如果我想輸出的是0-9呢?

那麼就應該這樣:

var a = [];
for(var i=0;i<10;i++){
   a[i]=(function(o){return function(){console.log(o)}})(i);
}

今天我在看let的時候,let為JavaScript新增了塊級作用域,用它所宣告的變數,只在let命令所在的程式碼塊內有效。

var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6

我又看了看它編譯成es5的樣子,這道面試題又多了兩個方法,其實重在理解es6的塊級作用域和原來的全域性作用域。

"use strict";
var a = [];
var _loop = function (i) {
  a[i] = function () {
    console.log(i);
  };
};
for (var i = 0; i < 10; i++) {
  _loop(i);
}