JavaScript中 var 和 let 的区别

作为ES6新特性之一的let,其与var的区别、其实现原理又是怎样的呢?

谈到varlet,不可避免的要提到JS的作用域

众所周知在JS中不像其他语言一样有块级作用域,它只有全局作用域及函数内部的局部作用域

var 是全局作用域,有变量提升的作用

下面是一道经典面试题,其结果是 // 5 5 5 5 5

  

因为var全局作用域,所以在for循环中声明的 i 就是一个全局变量,全局可用,每一次给 i 赋值都是给全局变量 i 赋值。

而setTimeout是异步事件(属于eventloop中的宏任务),所以在循环过程中setTimeout会进入事件队列等待时机执行,也就是在for循环执行结束之后才会执行,for循环执行完之后全局变量 i = 5,所以结果就是 // 5 5 5 5 5

那我们如何在for循环中同时使用setTimeout的时候得到我们想要的结果呢? // 0 1 2 3 4

实现这个结果方法很多

方法一  调用函数


如上采用函数调用的形式,因为函数调用属于同步任务,在执行for循环的过程中调用varFun同时把 i 的值传递给函数,在函数内部参数 i 就变成了函数内的局部作用域,varFun中的setTimeout访问的就是varFun内的参数,从而解决全局变量的问题。

方法二  立即执行函数


如上采用的就是在for循环中定义立即执行的匿名函数,同时把参数 i 的值绑定到匿名函数的作用域内,从而实现规避全局变量的问题。

方法三  把 var 改成 let


 我们只需要把for循环中的var改成let,即可实现输出结果为 // 0 1 2 3 4

因为let声明的是块级作用域,只能在代码块中使用,在js中一个{}我们也称之为一个代码块,每次循环会产生一个代码块,每个代码块中的都是一个新的变量 i

 经典面试题


答案是 // Hello李四

在js拿到这段代码首先会进行变量提升,实际提升之后代码是下面这个样子

外面的name实际上并没有起作用,主要是if里面的这个name。

在某些编程语言里面,if实际上也是一个块级作用域,在块级作用域里面声明的变量外面是不可以使用的。但是在JS里面,除了函数具备这个功能外再没有块级作用域了。所以在if里面声明的name会被提升到函数最顶部先行执行,然后判断name是不是undefined类型,因为没有赋值所以答案是true,所以打印出Hello李四。

改进代码


结果为  // Goodbye张三

因为使用的是let声明,没有变量提升。所以if判断里的name引用的是全局变量name,所以答案是  // Goodbye张三

 let的实现原理

通过采用匿名函数的形式把声明的变量变成局部作用与可用的变量,而不是全局变量,实现与var的区分

实现代码

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值