重读《深入理解ES6》 —— 块级作用域
栏目: JavaScript · 发布时间: 5年前
内容简介:在 ES5 中,我们通常会使用事实上,无论在全局作用域或者函数作用域中,只要通过其实,变量提升的机制,不太符合我们的编码习惯,我们常常希望代码能够按照顺序执行,这也符合一般人的逻辑习惯。为此 ES6 引入了块级作用域的概念。
在 ES5 中,我们通常会使用 var
来声明变量。在使用 var
声明变量的时候,通常会遇到变量声明提升的问题。这种机制会让很多初学者疑惑不解。其实当我们理解了一个变量通常包括 声明 和 赋值 两个部分,这个问题也就不难理解了。
// 1 console.log(a); // undefined var a = 3; // 2 function foo() { console.log(b); // undefined if (true) { var b = 2; } } 复制代码
事实上,无论在全局作用域或者函数作用域中,只要通过 var
关键字声明的变量,不论在哪里声明,都会被当成在当前作用域顶部声明的变量。
// 1 var a; console.log(a); a = 3; // 2 function foo() { var b; console.log(b); if (true) { b = 2; } } 复制代码
二、块级作用域
其实,变量提升的机制,不太符合我们的编码习惯,我们常常希望代码能够按照顺序执行,这也符合一般人的逻辑习惯。为此 ES6 引入了块级作用域的概念。
块级作用域其实就是词法作用域,我们的代码写在哪,就会在哪里执行,这更符合我们的编程习惯。我们常说的块包括 函数内部 和 {}之间的部分 。
为了实现块级作用域,ES6 采用 let
和 const
代替 var
来声明变量。用 let
和 const
声明的变量会把变量的作用域限制在当前的代码块中,并且声明的变量不会被提升。另外,用 let
声明的变量,在同一代码块内,禁止重复声明。
// 1、变量不会提升 console.log(a); // ReferenceError: a is not defined let a = 3; // 2、变量只能在当前作用域访问 if (true) { const b = 3; console.log(b); // 3 } console.log(b); // ReferenceError: b is not defined // 3、禁止重复声明 function foo() { let c = 3; let c = 4; // Identifier 'c' has already been declared } foo(); 复制代码
三、let 与 const 的区别
用 let
和 const
都可以创建一个块级作用域,唯一的区别是 const
用来声明一个常量,它的值一旦被设定后不可修改。所以,用 const
声明的常量必须初始化。
// 1、不可更改 const a = 1; a = 2; // TypeError: Assignment to constant variable. // 2、必须初始化 const b; // SyntaxError: Missing initializer in const declaration 复制代码
关于 const
声明的变量不可修改,有一个值得注意的地方就是用 const
声明一个对象。比如:
const tom = { age: 18, city: 'shanghai' }; tom.age = 19; // 这是可以的 复制代码
我们可以理解为,用 const
声明了一个变量 tom,将一个对象的引用地址赋值给变量 tom,只要这个引用地址不发生变化,内部的值是可以修改的。
四、循环中块级作用域
在 ES5 中,比较让人头疼的地方可能就是 for 循环了。在循环中,我们用 var
声明一个变量,循环结束后,我们其实是希望这个变量被销毁的。但由于 var
声明的变量具有声明提升的特性,所以当我们用 for 循环的时候,往往会污染我们的全局作用域。
for (var i = 0; i < 10; i++) { // do something } console.log(i); // 10 // 当循环结束的时候,其实我们是希望变量 i 可以被销毁的。 // 但其实它被留在了全局 复制代码
这个时候,我们使用 let
来声明循环中的变量,就可以轻易的解决这个问题。
for (let i = 0; i < 10; i++) { // do something } console.log(i); // ReferenceError: i is not defined // 可以看到,循环结束,变量 i 就被销毁了。 perfect~~ 复制代码
最后总结一下, let
和 const
帮助我们解决了不少问题,我们不会再为变量提升引发的种种问题而困惑了,同时在循环中使用 let
来代替 var
可以在循环结束的时候销毁变量,避免无用的变量影响全局。而当前使用块级绑定的最佳实践是:默认使用 const
,只在确定需要改变变量的值时,使用 let
,以最大化地避免错误的产生。
如果文章中有错误或表述不严谨的地方,欢迎指正。
也欢迎大家关注我的同名微信公众号:李等等扣丁
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 重读《深入理解ES6》—— 函数
- GFS论文重读
- APUEv3 - 重读笔记
- 重读 Redux 源码的感悟
- 重读 JVM - javac & javap
- 重读 JVM - ParNew & CMS GC
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。