《深入理解ES6》阅读笔记 --- 块级作用域

《深入理解ES6》阅读笔记 --- 块级作用域

这一小节让我想到很多年前阅读到Nicholas的那本红宝书,所讲的作用域以及Var。也许至今,还有一些人搞不明白变量提升的含义。如果你有幸在大学里写过C语言,其实这就很好理解了。一个我们所说明的变量其实包含声明,赋值两个部分,是否有看过在头文件里声明,或者在C函数体内先声明,比如:

int sayB(){
 int b;
 b = 1;
 return b;
}
sayB()

而JS中所提到的变量提升,与其非常类似,你在函数体内定义的变量,无论在哪里定义,都会提升到函数的顶部,比如:

function b(){
 console.log(v)  // ?会报错吗?
 if (true){
   var v = 1;
 }
}

// 其实不会,执行顺序会变成

function b(){
  var v;
  console.log(v)
  if (true){
    v = 1;
  }
}

好了,我们不复习之前的知识了,块级作用域顾名思义的其作用域在一个小块中,其中跟两个关键字有关系 letconst ,于是乎你用它们定义的变量,也就只能存在于块级作用域内了。

function b (){
 console.log(v)
 if (true){
   let v = 1;
 }
}

这个时候再打印v是会报错的,不像之前那样给你一个undefined。

通过这一小节的阅读,这应该是其中一个很大的知识点,以及知晓了一些有趣的事情,这和 let const有关。letconst定义的变量不会像var一样,覆盖到全局。以前我们用var来定义变量时,如果多写一个重名的,只会是最后一个覆盖之前的。但是,这里如果你用let或者const来定义时,必然会报错。而且 const 定义的变量是不允许再赋值的,但是它允许对于键的再赋值,比如:

const b = {a:1}

// b.a = 2 (YES)

可以说对于以前我印象中最深刻的是如果从数组里可以正确的获取到其数值,需要借助闭包来完成,而现在因为块级作用域的存在,你完全可以不必要像ES5那样借助闭包了。

for (let i = 0;i<j;i++){
  //i
}

这个时候可以很顺利的完成从[0...n] 的过程。

很明显,块级作用域在某些时候帮助我们节约了很多事情,不会像因为变量提升而带来的某些不可预知的奇怪问题。最后这一小节给出了最佳实践,同名而言,如果你定义的是一个预知的值(不再修改)那么你应该使用const,反之你应该使用let,尽量的避免使用var,当然你想定义一个全局变量除外。

编辑于 2018-08-12

文章被以下专栏收录