var VS let

2018-06-02  本文已影响21人  心谭

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。按道理应该是12。这是因为: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>

更多思考

<!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

上一篇 下一篇

猜你喜欢

热点阅读