let和var的区别

先看一个常见的例子:
var liList = document.querySelectorAll('li') // 共5个li
for( var i=0; i<liList.length; i++){
  liList[i].onclick = function(){
    console.log(i)
  }
}

输出结果:5 5 5 5 5
原因:var创建变量i(提升并初始化为undefined),所以全局只有一个i,执行循环,onclick为回调函数,等i循环完成后,回调函数才执行,所以输出都是5(最后执行的为i++,i变成了5)

var liList = document.querySelectorAll('li') // 共5个li
for( let i=0; i<liList.length; i++){
  liList[i].onclick = function(){
    console.log(i)
  }
}

输出结果:0 1 2 3 4
原因:每let i 一次,都有一个新的i出现(会重新执行一次块级作用域内的内容),而这个i只在当前的环境中工作,每次的点击事件都会和对应的区域绑定起来,所以输出0到4

那它怎么知道上一轮循环的值,从而计算出本轮循环的值?这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算


变量创建、初始化和赋值的过程

var:在代码执行之前就创建该变量,并将其初始化为 undefined

console.log(x);
var x = 2;
function foo(){
  console.log(y);
  var y = 1;  //函数内的变量是否会提升? 
}
foo();
  1. 先为foo()创建一个环境(如果不是函数内声明就是在全局环境中,例子里的x),找到foo中所有用var声明的变量(例子里的y),在这个环境中创建变量
  2. 将这些变量初始化为undefined
  3. 执行代码内容(赋值或者其他操作)

函数内的变量是否会提升?
从下图前两个的测试中可以看出结果依然是提升了

在这里插入图片描述
注意这里函数没有写返回值,所以有undefined

let:创建过程提升,但没有初始化,所以无法使用

{
  let x = 1;
  x = 2;
}
//定义在大括号内 & 严格模式

{
  console.log(x) // Uncaught ReferenceError: x is not defined
  let x = 1
}
//执行 log 时 x 还没初始化,所以不能使用(暂时性死区)
  1. 在环境中创建变量
  2. 执行代码
  3. 执行x = 1,将x初始化为1
  4. 执行x = 2,对x进行赋值(后续操作)
区别

var 声明的变量提升后会自动初始化为undefined,let 声明的不会自动初始化,所以无法使用

作用域

es5:全局作用域和函数作用域
es6:新增块级作用域,由{ }包裹的,if语句和for语句中的都算作块级作用域,而不是函数作用域

通过var定义的变量可以跨块作用域访问到:

if(true) {
  var x = 3;
}
  console.log(x); // 3

let声明的变量只能在块作用域里访问,不能跨块访问,也不能跨函数访问:

if(true) {
  let x = 3;
}
  console.log(x); // 3
 //这里在chrome测试的时候要清一下缓存,或者改一下变量名
遇到的一个问题:

在这里插入图片描述

参考:

https://fangyinghang.com/let-in-js/
https://www.cnblogs.com/fly_dragon/p/8669057.html
https://www.cnblogs.com/liangshuang/p/8506819.html
https://blog.csdn.net/unionz/article/details/80032048
https://www.jianshu.com/p/287e0bb867ae
感谢这三位作者分享的知识

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值