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