前端成长路

Javascrip—取出循环中特定的值

2017-03-14  本文已影响7人  ninja梅梅

一、ES5
在循环过程中,如下代码段不能按照编写的本意输出结果(本意是想输出6)。

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

由于作用域链的配置机制,导致它们arr[i]引用的都是同一变量i。当循环结束后它们都指向循环最后的结果(i=10),所以arr中每一个的值都是10.
为了能让程序输出想要的值,可以通过创建一个匿名函数强制让闭包的行为符合预期

var arr = [];
for(var i=0; i<10; i++){
     arr[i] = function(num){
           console.log(num)
      }(i);
}
//0
//1
...
//9

上面的代码会依次打印出0~9;由此我们编写如下代码:

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

在上面的程序中,没有直接将闭包赋值给arr[i],而是定义了一个匿名函数,并将立即执行该匿名函数的结果赋值给数组;此时再调用arr[6]();就能得到想要的结果了。
接下来看看在ES6中会有写什么样的惊喜。

二、ES6
ES6中新增了let命令,用于声明变量。所声明的变量只在let命令所在的代码块内有效。所以如要在循环中取特定的值可以用以下代码轻松解决。

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

这段代码和最上面第一段只有一个地方不同,就是在for循环里用let声明的变量而不是var。奇迹就这样产生了。由于变量ilet声明的,所以当前的i只在本轮循环中有效。所以每一次循环i都是一个新的变量,于是最后调用arr[6]()输出的是6.

上一篇 下一篇

猜你喜欢

热点阅读