var VS let

发布 : 2018-05-23 分类 : ES6 浏览 :
  • 目前,如果大量使用let,为了保证兼容性,webpack会将let转化为var语法(这就会生成冗余代码)。其实,结合ES6的模块化规范,还是推荐使用:var,以保证兼容老旧浏览器情况下减小代码体积
  • 随着浏览器逐步升级,let才是未来主流。

ES5下的var

由于js变量提升法则,var不仅仅在它的代码作用域有用!可以看以下demo。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<p>黄义军</p><br/>
<p>黄鑫</p><br/>
<script>
let ps = document.getElementsByTagName('p')
for(var i=0;i<ps.length;++i ) {
ps[i].onclick = e => console.log(i)
}
</script>
</body>
</html>

分别点击两段文字,控制台输出的都是2。按道理应该是12。这是因为:JavaScript引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。也就是说,var声明的变量的作用域并不是自身作用域。

当然了,可以利用闭包来规避这种问题,请看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<p>黄义军</p><br/>
<p>黄鑫</p><br/>
<script>
let ps = document.getElementsByTagName('p')
let _ = i => event => console.log(i) // 返回一个函数,并且函数内部取到了正确的 i 值
for(var i=0;i<ps.length;++i ) {
ps[i].onclick = _(i) // 传递的是:i的副本
}
</script>
</body>
</html>

ES6下的let

有了let,之前关于var的问题都解决了。强烈建议:将使用var的地方替换为let!!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<p>黄义军</p><br/>
<p>黄鑫</p><br/>
<script>
let ps = document.getElementsByTagName('p')
for(let i=0;i<ps.length;++i ) { // 利用let声明
ps[i].onclick = event => console.log(i)
}
</script>
</body>
</html>

更多思考

  • 如果在工程项目里面大量使用let,为了保证兼容性,webpack会将let转化为var语法(这就会生成冗余代码)。其实,结合ES6的模块化规范,还是推荐使用:var,以保证兼容老旧浏览器情况下减小代码体积

  • 关于结合of的问题(可以测试以下代码)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<p>黄义军</p><br/>
<p>黄鑫</p><br/>
<script>
// 错误写法:( 注意 i 的作用域)
let ps = document.getElementsByTagName('p')
let i = 0
for(let p of ps ) { // 利用let声明
p.onclick = event => console.log(i)
i+=1
}
// 正确写法:
// let ps = document.getElementsByTagName('p')
// let helper = (i) => e => console.log(i)
// let i = 0
// for(let p of ps ) { // 利用let声明
// p.onclick = helper(i)
// i+=1
// }
</script>
</body>
</html>
本文作者 : 董沅鑫
原文链接 : https://godbmw.com/passages/2018-05-23-var-vs-let/
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!

知识 & 情怀 | 二者兼得

微信扫一扫, 向我投食

微信扫一扫, 向我投食

支付宝扫一扫, 向我投食

支付宝扫一扫, 向我投食

留下足迹