Javascript中的var和let有什么区别呢?

204 阅读2分钟
先来看段代码,猜猜会输出什么呢?

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

  setTimeout(function(){

   console.log(new Date(),i) 

  },i*1000) 

 console.log(new Date(),i,'for循环外层')


答案:

Mon Mar 30 2020 21:47:31 GMT+0800 (中国标准时间) 6 "for循环外层

Mon Mar 30 2020 21:47:31 GMT+0800 (中国标准时间) 6 

Mon Mar 30 2020 21:47:32 GMT+0800 (中国标准时间) 6 

Mon Mar 30 2020 21:47:33 GMT+0800 (中国标准时间) 6 

Mon Mar 30 2020 21:47:34 GMT+0800 (中国标准时间) 6 

Mon Mar 30 2020 21:47:35 GMT+0800 (中国标准时间) 6 

Mon Mar 30 2020 21:47:36 GMT+0800 (中国标准时间) 6 


解析:
由于在JavaScript中没有块级作用域,所以在for循环中,通过var定义的变量是一个全局变量。循环每次访问到的变量i实际上都是同一个变量,setTimeout()是异步任务,for循环是同步任务,因此需要在for循环结束后才能执行和setTimeout(),此时访问到的i等于6,由于循环了6次,所以异步队列中有6个setTimeout(),依次执行,访问到的都是同一个i,同一个i不断增加所以打印六次



那么我们把程序换成let会怎么样子呢?

for(let i=0;i<=5;i++){

setTimeout(function(){

 console.log(new Date(),i)

 },i*1000) }

console.log(new Date(),i,'for循环外层')

答案:

Uncaught ReferenceError: i is not defined at <anonymous>:7:24 (anonymous) 

 Mon Mar 30 2020 22:18:25 GMT+0800 (中国标准时间) 0

 Mon Mar 30 2020 22:18:26 GMT+0800 (中国标准时间) 1

 Mon Mar 30 2020 22:18:27 GMT+0800 (中国标准时间) 2

Mon Mar 30 2020 22:18:28 GMT+0800 (中国标准时间) 3

Mon Mar 30 2020 22:18:29 GMT+0800 (中国标准时间) 4

 Mon Mar 30 2020 22:18:30 GMT+0800 (中国标准时间) 5


解析:为什么上面输出的都是6,这里变成了0-5了呢?因为

let定义了一个块级变量,在for循环中使用let定义的变量,作用域只在for循环中。那么每一个循环中都有一个专属的变量i,只有i小于等于5时,才会有当前循环,故输出的i的最大值也仅仅是5。又因为i是块级别作用域,故for循环外的console.log()因为暂时性死区报错。


以上,你get到了吗?