【JavaScript 声明变量】let、var、const

108 阅读4分钟

varlet 和 const 是 JavaScript 中用于声明变量的三种关键字,它们之间有一些关键的区别,这些区别主要体现在作用域、提升(hoisting)、重新赋值和重新声明方面。

  1. 作用域(Scope)
    • varvar 声明的变量具有函数作用域或全局作用域,具体取决于其声明位置。如果在函数内部声明,则其作用域为该函数;如果在函数外部声明,则为全局作用域
    • let 和 constlet 和 const 声明的变量具有块级作用域(block scope),即它们的作用域被限制在其声明的块({})内。这允许在块内部声明变量而不影响外部作用域。
<style>
    .item {
        width: 100px;
        height: 50px;
        border: solid 1px rgb(42, 156, 156);
        float: left;
        margin-right: 10px;
    }
</style>
<body>
    <div class="container">
        <h2 class="page-header">点击切换颜色</h2>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>
    <script>
        //获取div元素对象
        let items = document.getElementsByClassName('item');
        //遍历并绑定事件
        for(var i = 0;i<items.length;i++){
            items[i].onclick = function(){
                //修改当前元素的背景颜色
                // this.style.background = 'pink';
                items[i].style.background = 'pink';
            }
        }
        // 这里相当于
        // 由于var具有函数作用域或全局作用域,不具有块级作用域,
        //所以点击的时候会重复定义,会报错
        // {
        //     var i = 0
        // }
        // {
        //     var i = 1
        // }
        // {
        //     var i = 2
        // }
        console.log(window.i); 
        //这里输出3 是因为item只有三个元素 i 为 0 1 2 
        // 最后一次自增到3 的时候,获取不到item 于是输出3
    </script>
</body>

解决方法:这个时候只需要将var改为let,原因由上述作用域的定义所示

  //获取div元素对象
        let items = document.getElementsByClassName('item');
        //遍历并绑定事件
        //这里的var改为let
        for(let i = 0;i<items.length;i++){
            items[i].onclick = function(){
                //修改当前元素的背景颜色
                items[i].style.background = 'pink';
            }
        }
        // {
        //     let i = 0
        // }
        // {
        //     let i = 1
        // }
        // {
        //     let i = 2
        // }
 <script>
        //声明常量
        const SCHOOL = '尚硅谷';

        //1. 一定要赋初始值
        // const A;  
         // 不赋值初始值
        
        
         //2. 一般常量使用大写(潜规则)
        const a = 100;


        //3. 常量的值不能修改
        // SCHOOL = 'ATGUIGU'; //报错

        //4. 块儿级作用域 :作用域内
        const PLAYER = 'Aaaa';
        {
            const PLAYER = 'UZI';
            console.log(PLAYER);
            
        }
        console.log(PLAYER); 

        //5. 对于数组和对象的元素修改, 不算做对常量的修改, 不会报错
        const TEAM = ['UZI','MXLG','Ming','Letme'];
        TEAM.push('Meiko');
        console.log(TEAM);
  1. 提升(Hoisting)
    • varvar 声明的变量会被提升(hoisting)到其作用域的顶部,但变量的初始化不会提升。这意味着你可以在声明变量之前访问它(值为 undefined)。
<script>
      console.log(a);  // undefined
      
      var a = 2
      console.log(a);   //2
    </script>
  • let 和 constlet 和 const 声明的变量也会被提升,但它们不会被初始化,这意味着在声明之前访问这些变量会导致一个引用错误(ReferenceError)。
<script>
      console.log(a);  //报错
      
      let a = 2
      console.log(a);  
</script>
<script>
      console.log(a);  //报错
      
      const a = 2
      console.log(a);  
</script>
  1. 重新赋值(Reassignment)
    • var 和 let:使用 var 和 let 声明的变量都可以被重新赋值。
    • constconst 声明的变量必须被赋予一个初始值,并且这个值不能被重新赋值。但是,如果变量是一个对象或数组,那么你可以修改对象或数组内部的属性或元素,只是不能重新给变量分配一个全新的值。
  2. 重新声明(Redeclaration)
    • varvar 允许在同一个作用域内多次声明同一个变量,但后续声明不会改变变量的值(除非进行了赋值)。
    • let 和 constlet 和 const 不允许在同一个作用域内或同一块内重复声明同一个变量。尝试这样做会导致语法错误(SyntaxError)。
    <script>
        var a = 0
        let b = 1
        const C = 2

        console.log(a,b,C); // 0 1 2

        a = 3
        b = 4
        console.log(a,b); // 3 4
        
        C = 5  //报错
    </script>

总结

  • 使用 var 时,变量具有函数作用域或全局作用域,并允许提升和重新声明。
  • 使用 let 时,变量具有块级作用域,允许提升但初始化不会提升,支持重新赋值但不支持重新声明。
  • 使用 const 时,变量具有块级作用域,不允许重新赋值和重新声明,但可以修改复合类型(如对象和数组)的内部属性。

在现代 JavaScript 开发中,推荐使用 let 和 const 来声明变量,因为它们提供了更清晰的作用域和更严格的变量管理,有助于避免一些常见的错误。