JavaScript-变量的作用域、let、const详解

发布于:2023-01-02 ⋅ 阅读:(261) ⋅ 点赞:(0)

在 javascript 中,var 定义变量实际是有作用域的。

假设在函数体中声明,则在函数体外不可以使用(可以用"闭包"实现)

测试如下代码:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        function biu(){
            var x=1;
            x=x+1;
        }
        x=x+2;
    </script>
</head>
<body>

</body>
</html>

此时浏览器会提示最后一个x缺少作用域:

如果两个函数使用了相同的变量名,只要在函数内部就不冲突

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        function biu(){
            var x=1;
            x=x+1;
        }
        function biu2(){
            var x='A';
            x=x+1;
        }
    </script>
</head>
<body>

</body>
</html>

内部函数可以访问外部函数的成员,反之则不行,示例如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        function biu(){
            var x=1;

            function biu2(){
                var y=x+1; //2
            }
            var z=y+1; //报错
        }
    </script>
</head>
<body>

</body>
</html>

假设,内部函数变量和外部函数的变量重名,在JavaScript中函数查找从自身函数开始,由'内'向'外'查找,假设外部存在这个同名的函数变量,则内部函数会屏蔽外部函数的变量

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        function biu(){
            var x=1;

            function biu2(){
                var x='A';
                console.log('inner'+x);
            }
            console.log('outer'+x)
            biu2();
        }
        biu();
    </script>
</head>
<body>

</body>
</html>

js 会提升变量的作用域

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        function biu(){
            var x='x'+y;
            console.log(x)
            var y='y';
        }
        //上述代码等价于
        function biu2(){
            var y;
            var x='x'+y;
            console.log(x);
            y='u'
        }
        biu();
    </script>
</head>
<body>

</body>
</html>

结果:xundefined

说明:js执行引擎,自动提升了y的声明,但是不会提升变量y的赋值,这个是在js建立之初就存在的特性,需要养成规范,所有的变量定义都放在函数的的头部,不要乱放,便于代码维护

//规范写法
        function biu2(){
            var x=1,
                y=x+1,
                z,i; //undefined
        }

全局函数

<script>
        //全局变量
        var x=1;
        function f(){
            console.log(x);
        }
        f();
        console.log(x);
    </script>

全局对象 window

<script>
        var x='xxx';
        alert(x);
        alert(window.x);//默认所有的全局变量都会自动绑定在window对象上
    </script>

alert() 这个函数本身也是一个window的变量;

<script>
        var x='xxx';
        window.alert(x);
        var old_alert=window.alert;
        window.alert=function () {
            
        }
        //此时alert()失效
        window.alert(123);
        //恢复alert
        window.alert=old_alert;
        window.alert(456);
    </script>

说明JavaScript只有一个全局作用域,任何变量(函数也可以视为变量),假设没有在函数作用范围内找到,就会向外查找,如果在全局作用域都没有找到,就会报错RefrenceError

规范:

由于我们所有的全局变量都会绑定到我们的window上,如果不同的js文件使用了相同的全局变量,如何能够减少冲突? ---> 定义一个唯一全局变量

<script>
        //唯一全局变量
        var BiuApp={};
        //定义全局变量
        BiuApp.name='biubiu';
        BiuApp.add=function (a,b) {
            return a+b;
        }    
</script>

把自己的代码全部放在自己定义的唯一空间名字中,降低命名冲突的问题

jQuery中就是使用的该方法:jQuery.name,简便写法:$()

局部作用域 let:

<script>
        function aaa(){
            for (var i = 0; i < 100; i++) {
                console.log(i)
            }
            console.log(i+1)// 问题:i出了这个作用域还可以使用
        }
    </script>

ES6 let关键字,解决局部作用域冲突问题

<script>
        function aaa(){
            for (let i = 0; i < 100; i++) {
                console.log(i);
            }
            console.log(i+1);
        }
    </script>

建议都使用let去定义局部作用域的变量

常量const:

在ES6之前,怎么定义常量:只要用全部大写字母命名的变量就是常量,建议不要修改这样的值

<script>
        var PI='3.14';
        console.log(PI);
        PI='3.14125';//可以改变这个值
        console.log(PI);
    </script>

在ES6引入了常量关键字const:

本文含有隐藏内容,请 开通VIP 后查看