ES6之前的JavaScript变量由var声明,而var声明的变量是始终保存在内存中的,为了实现块级作用域,我们会使用闭包模拟,但实际上非常的不方便。ES6添加了let和const标识符,弥补了这些不足。
var和闭包我们先来了解一下var和闭包,下面用花括号生成一个块级作用域,在其内创建变量count:
{ var count = 5;}console.log(count);//5
我们可以看到在块级作用域外部仍然可以访问count变量。实际上这段代码等效为:
var count;{ count = 5;}console.log(count);//5
这就是说,变量count的声明被提升至函数顶部,而初始化操作仍旧留在原初执行。
如果想要模拟块级作用域,实际上我们要做的是在使用变量的时候为其赋值块级作用域的值。利用函数的特性(可以参考这里理解),再来看一下闭包:
(function(){ var count = 5; console.log(count);//5})();console.log(count);//报错,count未定义
之所以如此,是因为函数过程是动态执行的,因此在函数内的变量是动态创建的。
let和constES6之后就不需要这么麻烦了,可以看下面这个例子:
{ let count = 5; console.log(count);//5}console.log(count);//报错
总结一下,let和const声明的变量都是块级作用域,在块级作用域之外访问就会报错。
此外,他们还有另一个特性,那就是不允许重定义,像下面这样就会报错:
var value = 30;let value = 2;//报错,不能重复定义
const与let的区别在于:const必须初始化且只能初始化一次,若改变变量值就会报错。此外,const变量如果是对象,对象的属性可以修改。
另外我们需要注意一个特性,看下面的例子:
if(condition){ console.log(typeof value);//引用错误 let value = "blue";}
但是这样写就不会报错:
console.log(typeof value);//"undeined"if(condition){ let value = "blue";}循环中的块作用域绑定
看下面的例子:
for(var i=0;i<10;i++){ console.log(i);//0...9}console.log(i);//10
for(let i=0;i<10;i++){ console.log(i);//0...9}console.log(i);//报错
for(const i=0;i<10;i++){ console.log(i);//输出0后报错,因为const不能改变}console.log(i);//报错
但是const可以用在for-in或for-of中,不会报错,如下。
var obj = {a:true,b:true,c:true}for(const key in obj){ console.log(key);//a/b/c}全局块作用域绑定
当var被用于全局作用域时,它会创建一个新的全局变量作为全局对象(浏览器环境中的window对象)的属性。这样就有可能会出现下面的错误。
//在浏览器中var RegExp = "Hello!";console.log(window.RegExp );//"Hello!"
但使用let就不会出现这种错误。
//在浏览器中let RegExp = "Hello!";console.log(RegExp );//"Hello!"console.log(window.RegExp === RegExp);//false
最后建议:默认使用const,只有确实需要修改变量时使用let。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。