var let const的区别

500 阅读3分钟

ECMAScript变量是松散类型的,意思是变量可以用于保存任何的数据类型。每个变量只不过是一个用于保存任意值的命名占位符。有三个关键字可以声明变量:var、const和let。其中,var在ECMAScript版本中都可以使用,而const和let只能在ES6及更晚的版本中使用。

一、var与let的区别

const和let基本相同,唯一的区别是用它声明变量时必须同时初始化变量,而且它声明的变量是常量,无法改变。所以我们先讨论var与let的区别。

1.作用域不同

var声明的是函数作用域;而let声明的是块级作用域(包括函数作用域与if,for语句块),块级作用域是函数作用域的子集,所以let的作用域更小。

{
  var a = 1;
  let b = 1;
}
console.log(a); //1
console.log(b); //ReferenceError: b is not defined

一个经典案例

本例中使用for循环为item元素绑定点击事件,期望点击事件触发后元素变为红色。但是for循环内使用var声明变量时,会报错:tools.js: 53 Uncaught TypeError: Cannot read property 'className' of undefined.我们打印i的值会发现它为3。这是因为使用var声明的变量在块级作用域外也有效,所有每个循环内其实共享的是一个i变量,循环结束后i的值为3,此时绑定事件监听的语句相当于items[3].onclick = function(){ addClass(items[3], 'pink') } 但是items中只有3个元素,所以会报错

    <style>
        .item {
            width: 100px;
            height: 50px;
            border: solid 1px rgb(42, 156, 156);
            float: left;
            margin-right: 10px;
        }
        .pink{
            background-color: pink;
        }
    </style>
    <div class="container">
        <h2 class="page-header">点击切换颜色</h2>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>
     <script>
        let items = document.getElementsByClassName('item');
      //  alert(items[0])
        //遍历并绑定事件
        for(var i = 0; i < items.length; i++){
            items[i].onclick = function(){
                addClass(items[i],'pink')
            }
        }
        console.log(i)
    </script>

如果将循环改为用let声明变量,就不会报错,读者可以自己尝试

for(var i = 0; i < items.length; i++){
    items[i].onclick = function(){
       addClass(items[i],'pink')
    }
}

2.var存在变量提升

var声明的变量会自动提升函数作用域的顶部;而let不会,在let声明之前的执行瞬间被称为“暂时性死区”,此阶段引用任何后面才声明的变量都会抛出ReferenceError

console.log(a); //undefined
console.log(b); //ReferenceError: Cannot access 'b' before initialization
var a = 1;
let b = 1; 

不过需要注意的是,var声明的变量虽然会提声,但不会进行赋值,只有执行到var a = 1;时变量a的值才变为1。

3.var可以重复声明变量,而let不能

当使用let对一个变量重复声明时,js引擎会报错

var a = 1;
console.log(a) //1
var a = 2;
console.log(a) //2
let b = 1;
console.log(b)
let b = 2;
console.log(b) //SyntaxError: Identifier 'b' has already been declared

4.var声明的全局变量会默认变为window的属性

var a = 1;
let b = 1;
console.log(window.a) //1
console.log(window.b) //undefined

需要注意的是, window变量只有在浏览器环境下才有, 在node环境下的全局变量是global,用var声明的变量不会变为global的属性。

var a = 1;
let b = 1;
console.log(global.a) //undefined
console.log(global.b) //undefined

一、const与let的区别

1. const声明的变量必须有初始值

let a;
a = 1;
const b; //Missing initializer in const declaration
b = 1; 

2. const声明的变量不可修改

const a = 1;
a++; //TypeError: Assignment to constant variable.

需要注意的,对于基本变量而言,其值不能修改,但是对于引用变量,是指地址值不可修改,但是地址指向的内容是可以修改的。

const a = [1, 2, 3];
console.log(a) //[ 1, 2, 3]
a.push(4);
console.log(a) //[ 1, 2, 3, 4 ]