Let

来自姬鸿昌的知识库
跳到导航 跳到搜索

let 有几个特点:

1.变量不能重复声明

    <script>
        let name = '张三';
        let name = '李四';
    </script>

运行会在控制台报错 这一点和 var 不同

    <script>
        var name = '张三';
        var name = '李四';
    </script>

上面使用 var 的代码就可以正常运行。

2.块级作用域 全局,函数,eval

let 声明的变量只在代码块里有效,出代码块就无效了,就读取不到了

    <script>
        {
            let greeting = 'hello';
        }
        console.log(greeting);
    </script>

上面代码运行就不会输出,控制台会报错。如果换成 var:

    <script>
        {
            var greeting = 'hello';
        }
        console.log(greeting);
    </script>

就会正常输出,这是因为 var 没有块级作用域的概念,var 声明的属性会被添加到全局的属性 window 中,所以在花括号外就能读取到它,但 let 声明的变量就不行了,因为有块级作用域的概念,就只能在代码块里有效,所以在块外就读取不到了。

还有 if else while for,这些也都是块级作用域。

坑:做这个实验可别用什么 name 这种常见变量名,因为很可能已经被浏览器或者 Live Server 之类的用了

3.不存在变量提升

变量提升是:代码在执行之前,会先收集函数和 var 声明的变量,对于 var 声明的变量还会赋一个初始值 undefined

    <script>
        //在变量声明语句前,就可以输出变量
        console.log(greeting);
        var greeting = 'hello';
    </script>

上面的代码会在控制台输出 undefined,这是因为存在变量提升,上面的实际执行逻辑就像:

    <script>
        var greeting;
        //在变量声明语句前,就可以输出变量
        console.log(greeting);
        var greeting = 'hello';
    </script>

如果使用 let 声明,就会报错,因为 let 声明的变量不存在变量提升:

    <script>
        console.log(greeting);
        let greeting = 'hello';
    </script>

4.不影响作用域链

    <script>
        {
            let greeting = 'hello';
            function fn() {
                console.log(greeting);
            }
            fn();
        }
    </script>

正常运行,fn 函数作用域里没有 greeting,就会向上一层找 greeting 这个变量,然后就找到了,这就是作用域链的效果