JavaScript-变量作用域

在 JavaScript 中定义变量有两种方式

ES6 之前: var 变量名称;
ES6 开始: let 变量名称;

两种定义变量方式的区别

是否能够定义同名变量

通过 var 定义变量, 可以重复定义同名的变量, 并且后定义的会覆盖先定义的。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script type="text/javascript">
        var num = 123;
        var num = 456;
        console.log(num);
    </script>
</head>
<body>
</body>
</html>

如果通过 let 定义变量,"相同作用域内" 不可以重复定义同名的变量。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script type="text/javascript">
        let num = 123;

        // 报错 Uncaught SyntaxError: Identifier 'num' has already been declared
        let num = 456;
    </script>
</head>
<body>
</body>
</html>

是否能够先使用后定义

通过 var 定义变量, 可以先使用后定义 (预解析)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script type="text/javascript">
        console.log(num);
        var num = 123;
    </script>
</head>
<body>
</body>
</html>

通过 let 定义变量, 不可以先使用再定义 (不会预解析)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script type="text/javascript">
        // 报错 Uncaught ReferenceError: Cannot access 'num' before initialization at index.html?_ijt=37c9th389lfunccvo6ijq9ebdd:8
        console.log(num);

        let num = 123;
    </script>
</head>
<body>
</body>
</html>

是否能被 {} 限制作用域

无论是 var 还是 let 定义在 {} 外面都是全局变量。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script type="text/javascript">
        var num = 123;
        let num = 123;
    </script>
</head>
<body>
</body>
</html>

将 var 定义的变量放到一个单独的 {} 里面, 还是一个全局变量。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script type="text/javascript">
        {
            var num = 123;
        }

        // 不会报错
        console.log(num);
    </script>
</head>
<body>
</body>
</html>

将 let 定义的变量放到一个单独的 {} 里面, 是一个 局部变量

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script type="text/javascript">
        {
            let num = 123;
        }
        // 会报错 Uncaught ReferenceError: num is not defined
        console.log(num);
    </script>
</head>
<body>
</body>
</html>

在 JavaScript 中 {} 外面的作用域, 我们称之为全局作用域。
在 JavaScript 中函数后面 {} 中的的作用域, 我们称之为 "局部作用域"。
在 ES6 中只要 {} 没有和函数结合在一起, 那么应该称之为 "块级作用域"。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script type="text/javascript">
        {
            // 块级作用域
        }
        
        if (false) {
            // 块级作用域
        }
        
        while (false) {
            // 块级作用域
        }
        
        for (; ;) {
            // 块级作用域
        }
        
        do {
            // 块级作用域
        } while (false);
        
        switch () {
            // 块级作用域
        }

        function say() {
            // 局部作用域
        }
    </script>
</head>
<body>
</body>
</html>

块级作用域和局部作用域的区别

在块级作用域中通过 var 定义的变量是 全局变量

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script type="text/javascript">
        {
            // 块级作用域 ↓ 全局变量
            var num = 123;
        }
        console.log(num);
    </script>
</head>
<body>
</body>
</html>

在局部作用域中通过 var 定义的变量是 局部变量

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script type="text/javascript">
        function test() {
            // 局部变量
            var value = 666;
        }

        test();
        console.log(value);
    </script>
</head>
<body>
</body>
</html>

无论是在块级作用域还是在局部作用域, 省略变量前面的 let 或者 var 就会变成一个 全局变量

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
    <script type="text/javascript">
        function test() {
            // 全局变量
            value = 666;
        }

        test();
        console.log(value);
    </script>
</head>
<body>
</body>
</html>
posted @ 2021-07-02 10:20  BNTang  阅读(46)  评论(0编辑  收藏  举报