ES6中新增了let和const的定义变量的方法,都是定义变量的方法,那么它们之间的区别主要是什么呢?
让我们先看一下他们在MDN上的定义:
var声明语句声明一个变量,并可选地将其初始化为一个值。
let语句声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。
const常量是块级范围的,非常类似用let语句定义的变量。但常量的值是无法(通过重新赋值)改变的,也不能被重新声明。
var与let的区别
- 作用域
let存在块级作用域,它定义的变量只在其声明的块或子块中可用,而在函数内var声明的变量的作用域是整个封闭函数,在函数外var声明的变量则是全局变量,它的作用域是全局作用域
函数内:
function letTest(){
let testVal = 1;
{
let testVal = 2;
console.log(testVal); //2
}
console.log(testVal) //1
}
function varT(){
var testVal = 1;
{
var testVal = 2;
console.log(testVal); //2
}
console.log(testVal) //2
}
函数外:
{
let testVal = 1;
}
console.log(testVal); //testVal is not defined
{
var testValVar = 1;
}
console.log(testVal); //1
- 污染全局变量
在定义全局变量的时候,
let声明的变量不会在全局对象里新建一个属性,而var声明的变量则会在全局对象里新建一个属性
let testLet = 1;
var testVar = 2;
console.log(window.testLet) //undefined
console.log(window.testVar) //2
- 重复声名
let不允许重复声明同一变量,而var则可以多次重复声明
let repeatLet = 1;
let repeatLet = 2; //SyntaxError: Identifier 'repeatLet' has already been declared
console.log(repeatLet)
var repeatVar = 1;
var repeatVar = 2;
console.log(repeatVar) //2
- 暂存死区
与通过
var声明的有初始化值undefined的变量不同,通过let声明的变量直到它们的定义被执行时才初始化。
console.log(testVar); //undefined
console.log(testLet); //ReferenceError: Cannot access 'testLet' before initialization
var testVar = 1;
let testLet = 2;
报错内容是:初始化之前无法访问“testLet”,说的是初始化而不是“testLet is not defined”
const与let的区别
通过定义可以简单了解到二者的区别主要在于是否能够重新赋值。
- 重新赋值
let testLet = 1;
testLet = 2;
console.log(testLet); //2
const testConst = 1;
testConst = 2; //TypeError: Assignment to constant variable.
console.log(testConst);
const声明创建一个值的只读引用。但这并不意味着它所持有的值是不可变的,只是变量标识符不能重新分配。例如,在引用内容是对象的情况下,这意味着可以改变对象的内容(例如,其参数)。
const testConst = {a:1};
testConst.a = 2;
console.log(testConst.a); //2
- 初始化
let在声明变量的时候也会初始化为undefined,const则不会,其必须要有一个初始值;
const testCost; //SyntaxError: Missing initializer in const declaration
console.log(testCost);
...
let testLet;
console.log(testLet); //undefined
变量提升
在这里一般又会想到一个关于变量提升的问题。
从概念的字面意义上说,“变量提升”意味着变量和函数的声明会在物理层面移动到代码的最前面,但这么说并不准确。实际上变量和函数声明在代码里的位置是不会动的,而是在编译阶段被放入内存中。
而通过 let、const 声明的变量直到它们的定义被执行时才初始化,而var声明的时候就会默认初始化为undefined;
假设let、const不存在变量声明,那么请看下方代码
console.log(b)
let b = 9;
const c;
console.log(c)
如果不存在变量提升,那么代码会报错暂存死区,在第一行代码那里就应该报错‘ReferenceError: Cannot access 'b' before initialization’;
但实际代码执行的结果却是:
console.log(b)
let b = 9;
const c; //SyntaxError: Missing initializer in const declaration
console.log(c)
简单的认为在编译阶段let、const都进行了变量提升,更准确的说是声明提升,但并没有提升初始化;
变量可以在声明之前进行初始化和使用。但是如果没有初始化,就不能使用它们。
综合上方简单的认为var与let的区别主要有四点,而const与let的区别有两点。