详解js中let与var声明变量的区别


Posted in Javascript onApril 05, 2020

ES6 新增了let命令,用来声明局部变量,所声明的变量,只在let命令所在的代码块内有效,而且有暂时性死区的约束。

1.ES6可以用let定义块级作用域变量

代码如下:

function f1(){
  {
   var a = 10;
   let b = 20;
  }
  console.log(a); // 10
  console.log(b); // Uncaught ReferenceError: b is not defined
 }
 f1();

说明:在ES6之前只有全局作用域和函数作用域,在ES6中新增了块级作用域,用{}花括号表示。var 声明的变量a在花括号外面仍然是会起作用的,但是let声明的变量b只有在花括号里面才会起作用的,在块级作用域内。

2.let配合for循环的独特应用

代码如下:

function f2(){
  var i = 5;
  for(var i=0;i<=10;i++){

  }
  console.log(i); // 11

  var j = 5;
  for(let j=0;j<=10;j++){

  }
  console.log(j); // 5

 }
 f2();

说明:let非常适合用于for循环内部的块级作用域,在for循环当中,每一次的执行都是一个全新的独立的块级作用域。使用let声明的变量在for循环当中不会受到循环体外面的影响,不会受到变量污染,不会发生改变。对于var声明的变量i会受到for循环的影响,受到变量污染,而let声明的变量j不会受到for循环的影响。

3.let没有变量提升与暂时性死区

代码如下:

function f3(){

  // 变量提升
  function f31(){
   console.log(a); // undefined
   var a = 10;

   console.log(b); // Uncaught ReferenceError: b is not defined
   let b = 10;
  }
  f31();

说明:在ES6中,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。暂时性死区(TDZ):在代码块内,使用let命令声明变量之前,该变量都是不可用的。在f31函数中,用var声明的变量a发生了变量提升,打印出的值为undefined 未定义,而用let声明的变量b报错Uncaught ReferenceError,不会发生变量提升。在f32函数中,用使用let命令声明的变量a之前,都属于变量a的暂时性死区,形成封闭作用域,该变量都是不可用的,会报错,Uncaught ReferenceError: a is not defined。在let声明变量后,它是一个未定义的变量。当再给变量a进行赋值操作以后,它的值可以正常打印出来。

4.let变量不能重复声明

代码如下:

function f4(){
  let a = 10;
  let a = 20;
  console.log(a); // Uncaught SyntaxError: Identifier 'a' has already been declared

  let b = 10;
  var b = 20;
  console.log(b); // Uncaught SyntaxError: Identifier 'b' has already been declared

 }
 f4();

说明:let不允许在相同作用域内,重复声明同一个变量,否则报错。在函数f4中,无论是用两个let声明同一个变量a,还是一个let声明变量b和一个var声明变量b,都是会报错的,Uncaught SyntaxError: Identifier ‘a' has already been declared 和 Uncaught SyntaxError: Identifier ‘b' has already been declared , 所以不能够重复声明同一个变量。

JS中的let和var的区别补充

最近很多前端的朋友去面试被问到let和var的区别,其实阮一峰老师的ES6中已经很详细介绍了let的用法和var的区别。我简单总结一下,以便各位以后面试中使用。

ES6 新增了let命令,用来声明局部变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效,而且有暂时性死区的约束。

先看个var的常见变量提升的面试题目:

//题目1:
var a = 99;      // 全局变量a
f();          // f是函数,虽然定义在调用的后面,但是函数声明会提升到作用域的顶部。 
console.log(a);    // a=>99, 此时是全局变量的a
function f() {
 console.log(a);   // 当前的a变量是下面变量a声明提升后,默认值undefined
 var a = 10;
 console.log(a);   // a => 10
}

// 输出结果:
undefined
10
99

如果以上题目有理解困难的童鞋,请系统的看一下老马的免费JS高级视频教程。

ES6可以用let定义块级作用域变量

在ES6之前,我们都是用var来声明变量,而且JS只有函数作用域和全局作用域,没有块级作用域,所以{}限定不了var声明变量的访问范围。

例如:

{ 
 var i = 9;
} 
console.log(i); // 9

ES6新增的let,可以声明块级作用域的变量。

{ 
 let i = 9;   // i变量只在 花括号内有效!!!
} 
console.log(i); // Uncaught ReferenceError: i is not defined

let 配合for循环的独特应用

let非常适合用于 for循环内部的块级作用域。JS中的for循环体比较特殊,每次执行都是一个全新的独立的块作用域,用let声明的变量传入到 for循环体的作用域后,不会发生改变,不受外界的影响。看一个常见的面试题目:

for (var i = 0; i <10; i++) { 
 setTimeout(function() { // 同步注册回调函数到 异步的 宏任务队列。
  console.log(i);    // 执行此代码时,同步代码for循环已经执行完成
 }, 0);
}
// 输出结果
10  共10个
// 这里面的知识点: JS的事件循环机制,setTimeout的机制等

如果把 var改成 let声明:

// i虽然在全局作用域声明,但是在for循环体局部作用域中使用的时候,变量会被固定,不受外界干扰。
for (let i = 0; i < 10; i++) { 
 setTimeout(function() {
  console.log(i);  // i 是循环体内局部作用域,不受外界影响。
 }, 0);
}
// 输出结果:
0 1 2 3 4 5 6 7 8 9

let没有变量提升与暂时性死区

用let声明的变量,不存在变量提升。而且要求必须 等let声明语句执行完之后,变量才能使用,不然会报Uncaught ReferenceError错误。
例如:

console.log(aicoder);  // 错误:Uncaught ReferenceError ...
let aicoder = 'aicoder.com';
// 这里就可以安全使用aicoder

ES6 明确规定,如果区块中存在letconst命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。

总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。

let变量不能重复声明

let不允许在相同作用域内,重复声明同一个变量。否则报错:Uncaught SyntaxError: Identifier 'XXX' has already been declared

例如:

let a = 0;
let a = 'sss';
// Uncaught SyntaxError: Identifier 'a' has already been declared

总结

ES6的let让js真正拥有了块级作用域,也是向这更安全更规范的路走,虽然加了很多约束,但是都是为了让我们更安全的使用和写代码。

以上所述是小编给大家介绍的let与var声明变量区别详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jquery 新浪网易的评论块制作
Jul 01 Javascript
JavaScript控制listbox列表框的项目上下移动的方法
Mar 18 Javascript
Bootstrap+jfinal退出系统弹出确认框的实现方法
May 30 Javascript
jQuery自制提示框tooltip改进版
Aug 01 Javascript
深入理解node.js之path模块
May 03 Javascript
jQuery实现的简单无刷新评论功能示例
Nov 08 jQuery
Vue 按键修饰符处理事件的方法
May 04 Javascript
JS滚轮控制图片缩放大小和拖动的实例代码
Nov 20 Javascript
ES6知识点整理之函数对象参数默认值及其解构应用示例
Apr 17 Javascript
vue-test-utils初使用详解
May 23 Javascript
jquery实现Ajax请求的几种常见方式总结
May 28 jQuery
keep-Alive搭配vue-router实现缓存页面效果的示例代码
Jun 24 Javascript
webpack中如何加载静态文件的方法步骤
May 18 #Javascript
微信小程序实现录音时的麦克风动画效果实例
May 18 #Javascript
vue+egg+jwt实现登录验证的示例代码
May 18 #Javascript
egg.js的基本使用和调用数据库的方法示例
May 18 #Javascript
inquirer.js一个用户与命令行交互的工具详解
May 18 #Javascript
webpack 代码分离优化快速指北
May 18 #Javascript
如何实现小程序tab栏下划线动画效果
May 18 #Javascript
You might like
PHP生成网页快照 不用COM不用扩展.
2010/02/11 PHP
PHP中header和session_start前不能有输出原因分析
2013/01/11 PHP
yii的CURD操作实例详解
2014/12/04 PHP
py文件转exe时包含paramiko模块出错解决方法
2016/08/12 PHP
PHP针对redis常用操作实例详解
2019/08/17 PHP
tp5递归 无限级分类详解
2019/10/18 PHP
How to Auto Include a Javascript File
2007/02/02 Javascript
javascript针对DOM的应用实例(一)
2012/04/15 Javascript
Jquery和angularjs获取check框选中的值的方法汇总
2016/01/17 Javascript
谷歌showModalDialog()方法不兼容出现对话窗口的解决办法
2016/02/15 Javascript
AngularJS控制器详解及示例代码
2016/08/16 Javascript
JQuery 动态生成Table表格实例代码
2016/12/02 Javascript
使用jquery给新生的th绑定hover事件的实例
2017/02/10 Javascript
利用js的闭包原理做对象封装及调用方法
2017/04/07 Javascript
关于Ajax的原理以及代码封装详解
2017/09/08 Javascript
XMLHttpRequest对象_Ajax异步请求重点(推荐)
2017/09/28 Javascript
vue-router 组件复用问题详解
2018/01/22 Javascript
jQuery实现DIV响应鼠标滑过由下向上展开效果示例【测试可用】
2018/04/26 jQuery
node 使用 async 控制并发的方法
2018/05/07 Javascript
javascript事件监听与事件委托实例详解
2019/08/16 Javascript
jQuery 查找元素操作实例小结
2019/10/02 jQuery
Python 运行 shell 获取输出结果的实例
2019/01/07 Python
Python实现判断一个整数是否为回文数算法示例
2019/03/02 Python
python2.7的flask框架之引用js&amp;css等静态文件的实现方法
2019/08/22 Python
在django中使用apscheduler 执行计划任务的实现方法
2020/02/11 Python
Django查询优化及ajax编码格式原理解析
2020/03/25 Python
解决python 虚拟环境删除包无法加载的问题
2020/07/13 Python
Python中的流程控制详解
2021/02/18 Python
PHP面试题集
2016/12/18 面试题
历史学专业大学生找工作的自我评价
2013/10/16 职场文书
公务员爱岗敬业演讲稿
2014/08/26 职场文书
创业计划书之牛肉汤快餐店
2019/10/08 职场文书
Golang 实现超大文件读取的两种方法
2021/04/27 Golang
解决numpy和torch数据类型转化的问题
2021/05/23 Python
MySQL索引失效的典型案例
2021/06/05 MySQL
使用CSS连接数据库的方式
2022/02/28 HTML / CSS