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的块级别作用域
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语法教程
以及勤奋的本人,集体博客,GitHub