阅读 16

var,let,const 小记

ES6中新增了let和const的定义变量的方法,都是定义变量的方法,那么它们之间的区别主要是什么呢?

让我们先看一下他们在MDN上的定义:

var 声明语句声明一个变量,并可选地将其初始化为一个值。
let 语句声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。
const 常量是块级范围的,非常类似用 let语句定义的变量。但常量的值是无法(通过重新赋值)改变的,也不能被重新声明。

var与let的区别

  1. 作用域

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
复制代码
  1. 污染全局变量

在定义全局变量的时候,let声明的变量不会在全局对象里新建一个属性,而var声明的变量则会在全局对象里新建一个属性

let testLet = 1;
var testVar = 2;
console.log(window.testLet)    //undefined
console.log(window.testVar)    //2
复制代码
  1. 重复声名

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
复制代码
  1. 暂存死区

与通过  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的区别

通过定义可以简单了解到二者的区别主要在于是否能够重新赋值。

  1. 重新赋值
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
复制代码
  1. 初始化

let在声明变量的时候也会初始化为undefined,const则不会,其必须要有一个初始值;

const testCost;    //SyntaxError: Missing initializer in const declaration
console.log(testCost);
...
let testLet;
console.log(testLet);    //undefined
复制代码

变量提升

在这里一般又会想到一个关于变量提升的问题。

从概念的字面意义上说,“变量提升”意味着变量和函数的声明会在物理层面移动到代码的最前面,但这么说并不准确。实际上变量和函数声明在代码里的位置是不会动的,而是在编译阶段被放入内存中。

而通过 letconst 声明的变量直到它们的定义被执行时才初始化,而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)
复制代码

简单的认为在编译阶段letconst都进行了变量提升,更准确的说是声明提升,但并没有提升初始化;

变量可以在声明之前进行初始化和使用。但是如果没有初始化,就不能使用它们。

综合上方简单的认为var与let的区别主要有四点,而const与let的区别有两点。

文章分类
前端
文章标签