ES6中的块作用域

  除了javascript之外很多编程语言都有支持块级作用域,但是在es6之前js是没有创建完整,不受约束的块作用域的能力的。对于其他编程语言的人来说对于块作用域和熟悉但是对于主要使用js的开发人员来说活血块作用域很陌生。

如下代码:

for (var i = 0; i < 6;i++) {
  console.log(i);      
}

这里定义了循环变量i,通常是因为只想在for的循环上使用这个i变量,但是有件事情可能会被你忽略的就是,这个i变量会意外的被提升到外部作用域中,或者全局或者函数中。如果变量被意外的提升在你未知的作用域中的话,将会导致未知的变量异常,或者变量被意外的混乱的复用,这将影响代码的可维护性。

在这种情况下我们需要使用到ES6中新引入的关键字let。它是var的另外一种变量声明方式。let关键字可以将变量绑定到所在块作用域中。

var s = true;
if (s) {
  let bar = 'hello';
  console.log(bar);    
}

如上代码 bar变量的值只存在于{} 这个块作用域中。另外也可以在声明中的任意位置都可以使用{}括号来为let创建一个用于绑定的块。

if (s) {
  {
     let sample = "sample";
     console.log(sample);        
  }  
}

块作用域给我们带来的另外个好处就是,整个块可以被方便地移动而不会对外部if声明的位置和语义产生影响。

还有一点重要的特性就是,使用let进行声明的变量不会在块作用域中进行提升。

{
  console.log(demo); // 产生引用错误。
  let demo = 2;
}

有个常见的js变量提升的问题:

for (var i =0; i < 6; i++) {
    setTimeout(function () {
      console.log(i);
    }, 0)
  }

这个打印出的结果是多少呢? 如果你不知道这里的变量会被提升,你可能会以为是打印0-5的值,但是事实是它会打印出6个6。(当然这个还涉及到计时器的问题),那如何让他打印出预期的0,1,2,3,4,5的值呢?其中有一种ES6之前的解决方法就是使用IIFE表达式来解决。另一种方式就是将var 声明改为let声明形成块作用域。

posted @ 2018-03-14 00:21  我叫果果  阅读(120)  评论(0编辑  收藏  举报