背景
事实上var的设计可以看成JavaScript语言设计上的错误. 但是这种错误多半不能修复和移除, 以为需要向后兼容.
- 大概十年前, Brendan Eich就决定修复这个问题, 于是他添加了一个新的关键字: let
- 我们可以将let看成更完美的var
块级作用域
- JS中使用var来声明一个变量时, 变量的作用域主要是和函数的定义有关
- 针对于其他块定义来说是没有作用域的,比如if/for等,这在我们开发中往往会引起一些问题
举例说明
-
if的举例 var func; if (true){ var name = 'why' func = function () { console.log(name) } } name = '哈哈哈' func()
此处打印的log是”哈哈哈“而不是'why'
- for的举例
<button>按钮1</button> <button>按钮2</button> <button>按钮3</button> <button>按钮4</button> <script> var btns = document.getElementsByTagName("button"); for(var i =0; i< btns.length; ++i){ // 打印的都是第4次 btns[i].addEventListener('click', function () { console.log('第' + i + '个按钮被点击') }) } </script> 此处无论点击哪个按钮,日志都是打印的”第四个按钮被点击“。而为了解决这个问题,只能使用闭包的写法,因为var只支持全局和函数级的作用域,闭包写法如下 var btns = document.getElementsByTagName("button"); for(var i =0; i< btns.length; ++i){ (function (i) { btns[i].addEventListener('click', function () { console.log('第' + i + '个按钮被点击') }) })(i) }
- 使用let重写第二个例子
const btns = document.getElementsByTagName("button"); for (let i =0; i<btns.length; ++i){ btns[i].addEventListener('click', function () { console.log('第' + i + '个按钮被点击') }) }
此时点击的按钮都是对应的
总结
var仅支持全局和函数级的作用域,而不支持if和for级的作用域,若想实现可以使用闭包的方式实现
let天生支持if和for级的作用域,无需再次使用闭包方式实现