ES5下的var
由于
js
变量提升法则,var
不仅仅在它的代码作用域有用!可以看以下demo。
<!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
。按道理应该是1
或2
。这是因为:JavaScript
引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。也就是说,var
声明的变量的作用域并不是自身作用域。
当然了,可以利用闭包来规避这种问题,请看:
<!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
!!!
<!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
的问题(可以测试以下代码)
<!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>
欢迎技术交流,引用请注明出处。
个人网站:godbmw.com
Github:godbmw
网友评论