详解js中let与var声明变量的区别
ES6新增了let命令,用来声明局部变量,所声明的变量,只在let命令所在的代码块内有效,而且有暂时性死区的约束。
1.ES6可以用let定义块级作用域变量
代码如下:
functionf1(){ { vara=10; letb=20; } console.log(a);//10 console.log(b);//UncaughtReferenceError:bisnotdefined } f1();
说明:在ES6之前只有全局作用域和函数作用域,在ES6中新增了块级作用域,用{}花括号表示。var声明的变量a在花括号外面仍然是会起作用的,但是let声明的变量b只有在花括号里面才会起作用的,在块级作用域内。
2.let配合for循环的独特应用
代码如下:
functionf2(){ vari=5; for(vari=0;i<=10;i++){ } console.log(i);//11 varj=5; for(letj=0;j<=10;j++){ } console.log(j);//5 } f2();
说明:let非常适合用于for循环内部的块级作用域,在for循环当中,每一次的执行都是一个全新的独立的块级作用域。使用let声明的变量在for循环当中不会受到循环体外面的影响,不会受到变量污染,不会发生改变。对于var声明的变量i会受到for循环的影响,受到变量污染,而let声明的变量j不会受到for循环的影响。
3.let没有变量提升与暂时性死区
代码如下:
functionf3(){ //变量提升 functionf31(){ console.log(a);//undefined vara=10; console.log(b);//UncaughtReferenceError:bisnotdefined letb=10; } f31();
说明:在ES6中,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。暂时性死区(TDZ):在代码块内,使用let命令声明变量之前,该变量都是不可用的。在f31函数中,用var声明的变量a发生了变量提升,打印出的值为undefined未定义,而用let声明的变量b报错UncaughtReferenceError,不会发生变量提升。在f32函数中,用使用let命令声明的变量a之前,都属于变量a的暂时性死区,形成封闭作用域,该变量都是不可用的,会报错,UncaughtReferenceError:aisnotdefined。在let声明变量后,它是一个未定义的变量。当再给变量a进行赋值操作以后,它的值可以正常打印出来。
4.let变量不能重复声明
代码如下:
functionf4(){ leta=10; leta=20; console.log(a);//UncaughtSyntaxError:Identifier'a'hasalreadybeendeclared letb=10; varb=20; console.log(b);//UncaughtSyntaxError:Identifier'b'hasalreadybeendeclared } f4();
说明:let不允许在相同作用域内,重复声明同一个变量,否则报错。在函数f4中,无论是用两个let声明同一个变量a,还是一个let声明变量b和一个var声明变量b,都是会报错的,UncaughtSyntaxError:Identifier‘a'hasalreadybeendeclared和UncaughtSyntaxError:Identifier‘b'hasalreadybeendeclared,所以不能够重复声明同一个变量。
JS中的let和var的区别补充
最近很多前端的朋友去面试被问到let和var的区别,其实阮一峰老师的ES6中已经很详细介绍了let的用法和var的区别。我简单总结一下,以便各位以后面试中使用。
ES6新增了let命令,用来声明局部变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效,而且有暂时性死区的约束。
先看个var的常见变量提升的面试题目:
//题目1: vara=99;//全局变量a f();//f是函数,虽然定义在调用的后面,但是函数声明会提升到作用域的顶部。 console.log(a);//a=>99,此时是全局变量的a functionf(){ console.log(a);//当前的a变量是下面变量a声明提升后,默认值undefined vara=10; console.log(a);//a=>10 } //输出结果: undefined 10 99
如果以上题目有理解困难的童鞋,请系统的看一下老马的免费JS高级视频教程。
ES6可以用let定义块级作用域变量
在ES6之前,我们都是用var来声明变量,而且JS只有函数作用域和全局作用域,没有块级作用域,所以{}限定不了var声明变量的访问范围。
例如:
{ vari=9; } console.log(i);//9
ES6新增的let,可以声明块级作用域的变量。
{ leti=9;//i变量只在花括号内有效!!! } console.log(i);//UncaughtReferenceError:iisnotdefined
let配合for循环的独特应用
let非常适合用于for循环内部的块级作用域。JS中的for循环体比较特殊,每次执行都是一个全新的独立的块作用域,用let声明的变量传入到for循环体的作用域后,不会发生改变,不受外界的影响。看一个常见的面试题目:
for(vari=0;i<10;i++){ setTimeout(function(){//同步注册回调函数到异步的宏任务队列。 console.log(i);//执行此代码时,同步代码for循环已经执行完成 },0); } //输出结果 10共10个 //这里面的知识点:JS的事件循环机制,setTimeout的机制等
如果把var改成let声明:
//i虽然在全局作用域声明,但是在for循环体局部作用域中使用的时候,变量会被固定,不受外界干扰。 for(leti=0;i<10;i++){ setTimeout(function(){ console.log(i);//i是循环体内局部作用域,不受外界影响。 },0); } //输出结果: 0123456789
let没有变量提升与暂时性死区
用let声明的变量,不存在变量提升。而且要求必须等let声明语句执行完之后,变量才能使用,不然会报UncaughtReferenceError错误。
例如:
console.log(aicoder);//错误:UncaughtReferenceError... letaicoder='aicoder.com'; //这里就可以安全使用aicoder
ES6明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporaldeadzone,简称TDZ)。
let变量不能重复声明
let不允许在相同作用域内,重复声明同一个变量。否则报错:UncaughtSyntaxError:Identifier'XXX'hasalreadybeendeclared
例如:
leta=0; leta='sss'; //UncaughtSyntaxError:Identifier'a'hasalreadybeendeclared
总结
ES6的let让js真正拥有了块级作用域,也是向这更安全更规范的路走,虽然加了很多约束,但是都是为了让我们更安全的使用和写代码。
以上所述是小编给大家介绍的let与var声明变量区别详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!