博客说明
文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢!
在ES5中没有块级作用域,这出现了许多的问题,ES6中新增了块级作用域
由于使用var声明的变量,存在变量提升,在内层的tmp会覆盖掉外层的tmp变量
var tmp = ‘hahaha‘;
function f() {
  console.log(tmp);
  if (false) {
    var tmp = ‘hello world‘;
  }
}
f(); // undefined
在使用for循环时,i变量在循环结束之后并没有回收,而是泄漏成了全局变量
var s = ‘hahaha‘;
for (var i = 0; i < s.length; i++) {
  console.log(s[i]);
}
console.log(i); // 6
let和const为JavaScript新增了块级作用域
在同一个块级里面,外层代码块不受内层代码块的影响
function f1() {
  let n = 5;
  if (true) {
    let n = 10;
  }
  console.log(n); // 5
}
ES5 规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。但是,浏览器没有遵守这个规定,为了兼容以前的旧代码,还是支持在块级作用域之中声明函数,因此上面两种情况实际都能运行,不会报错。
像以下的代码,在ES5中是非法的,但是在浏览器中不会报错的
// 情况一
if (true) {
  function f() {}
}
// 情况二
try {
  function f() {}
} catch(e) {
  // ...
}
虽然不报错,但是ES6还是解决了这个问题,ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。
ES6 规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。
但是这样改动对老代码十分不友好,为了减轻因此产生的不兼容问题,ES6 在附录 B里面规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式。
var,即会提升到全局作用域或函数作用域的头部。注意,上面三条规则只对 ES6 的浏览器实现有效,其他环境的实现不用遵守,还是将块级作用域的函数声明当作let处理。
考虑到环境导致的行为差异太大,应该避免在块级作用域内声明函数。如果确实需要,也应该写成函数表达式,而不是函数声明语句。
// 块级作用域内部的函数声明语句,建议不要使用
{
  let a = ‘secret‘;
  function f() {
    return a;
  }
}
// 块级作用域内部,优先使用函数表达式
{
  let a = ‘secret‘;
  let f = function () {
    return a;
  };
}
ES6 的块级作用域必须有大括号,也就是标识,如果没有大括号,JavaScript 引擎就认为不存在块级作用域。
if (true) let x = 1;  // 报错
if (true) {
  let x = 1;
}
// 不报错
感谢
万能的网络
菜鸟教程
阮一峰的es6语法教程
原文:https://www.cnblogs.com/guizimo/p/14957449.html