for循环中var和let的迥异

for循环中var和let的迥异

昨天看到一同学碰到一个js的for循环问题,没想到使用for和使用var竟然有这么大的不同,之前都没有注意到这个问题,今天就写下记录下我的一些见解,如有不对之处,请做个正义的键盘侠狠狠的批评指正我。感谢感谢。。。

代码对比:

//用var声明变量
for(var i=0;i<5;i++){
  setTimeout(()=>{
    console.log(i);//5个5
  },100) 
}
console.log(i);//5

//用let声明变量
for(let j=0;j<5;j++){
  setTimeout(()=>{
    console.log(j);//0,1,2,3,4
  },100) 
}
console.log(j);//报错 j is not defined

我们不禁会产生这样的疑问?
为什么 用let就可以显示正确结果,而var就不可以呢?

因为var是全局作用域,有变量提升的作用,所以在for中定义一个变量,全局可以使用,循环中的每一次给变量i赋值都是给全局变量i赋值
另外这也牵涉到异步。 在var里面:
setTimeout是异步执⾏,10ms后往任务队列⾥⾯添加⼀个任务,只有主线线上的全部执⾏完,才会执⾏任务队列⾥的任务,当主线执⾏完成后,i是5,所以此时再去执⾏任务队列⾥的任务时,i全部是5了。对于打印5次是:
每⼀次for循环的时候,settimeout都执⾏⼀次,但是⾥⾯的函数没有被执⾏,⽽是被放到了任务队列⾥⾯,等待执⾏,for循环了5次,就放了5次,当主线程执行完成后,才进入任务队列里面执行。

let是块级作用域,只能在代码块中起作用,在js中一个{}中的语句我们也称为叫一个代码块,每次循环会产生一个代码块,每个代码块中的都是一个新的变量j; 在let里面:
因为for循环头部的let不仅将i绑定到for循环中,事实上它将其重新绑定到循环体的每一次迭代中,确保上一次迭代结束的值重新被赋值。setTimeout里面的function()属于一个新的域**,通过var定义的变量是无法传入到这个函数执行域中的**,通过使用let来声明块变量能作用于这个块,所以function就能使用i这个变量了。
斜体样式*

通过var定义的变量是无法传入到这个函数执行域中的

*可能大家对这句话不是很清楚,下面我用个例子演示下
{}代表一个块,这个时候let声明的变量只在这个块中起作用,而这个块对var声明的变量不起作用。因为var是全局作用域

let b=1;
var b=2;
 
// Uncaught SyntaxError: Identifier 'a' has already been declared
//let不能重复声明

我们使用let声明for循环变量,就是这个原因。
请大家细品下面这句话
let是块级作用域,只能在代码块中起作用,在js中一个{}中的语句我们也称为叫一个代码块,每次循环会产生一个代码块,每个代码块中的都是一个新的变量j; 在let里面:
因为for循环头部的let不仅将i绑定到for循环中,事实上它将其重新绑定到循环体的每一次迭代中,确保上一次迭代结束的值重新被赋值。setTimeout里面的function()属于一个新的域

使用let声明变量
for(let j=0;j<5;j++){
  setTimeout(()=>{
    console.log(j);//0,1,2,3,4
  },100) 
}
//实际上就是
{let j=0;setTimeout()=>{...}}
{let j=1;setTimeout()=>{...}}
{let j=2;setTimeout()=>{...}}
{let j=3;setTimeout()=>{...}}
{let j=4;setTimeout()=>{...}}
//用var声明变量
for(var i=0;i<5;i++){
  setTimeout(()=>{
    console.log(i);//5个5
  },100) 
}
//实际上是
var i=0;
var i=1;
var i=2;
var i=3;
var i=4;
setTimeout(()=>{
    console.log(i);

let 和var的作用域区别

{
  let a=123;
}
{
  let a=456;
}
console.log(a);//a is not defined;
{ 
  var b=1;
}
{ 
  var b=2;
}
console.log(b);// 2;

{}代表一个块,这个时候let声明的变量只在这个块中起作用,而这个块对var声明的变量不起作用。因为var是全局作用域。

let a=1;
let a=2;
//Uncaught SyntaxError: Identifier 'a' has already been declared
//let不能重复声明

let b=1;
var b=2;

// Uncaught SyntaxError: Identifier 'a' has already been declared
//let不能重复声明


var c=3;
var c=4;
console.log(c)//4;var可以重复声明


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值