ES6 块级作用域解决的一些问题

博客阐明

文章所波及的材料来自互联网整顿和集体总结,意在于集体学习和教训汇总,如有什么中央侵权,请分割自己删除,谢谢!

简介

ES5中没有块级作用域,这呈现了许多的问题,ES6中新增了块级作用域

问题一:内层变量笼罩外层变量

因为应用var申明的变量,存在变量晋升,在内层的tmp会笼罩掉外层的tmp变量

var tmp = 'hahaha';function f() {  console.log(tmp);  if (false) {    var tmp = 'hello world';  }}f(); // undefined

问题二:在for循环中的循环变量透露为全局变量

在应用for循环时,i变量在循环完结之后并没有回收,而是透露成了全局变量

var s = 'hahaha';for (var i = 0; i < s.length; i++) {  console.log(s[i]);}console.log(i); // 6

ES6的块级别作用域

letconst为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语法教程

以及勤奋的本人,集体博客,GitHub