【ES6】--浅析let、const和var

发布时间 2023-06-02 15:16:51作者: karen哈哈哈

  在ea6中添加了letconst命令,在这之前都是用的 var命令来变量声明。曾经面试被问为什么es6为增加let和 const这两命令,但当时的自己只停留在知道这两个命令和怎么去用这两个命令的阶段,至于原因是什么,确实是没关注过。

一、ES6中为什么会添加let和const?

  首先,我们要知道只使用var命令声明变量时,出现了什么问题导致不能只使用这个命令。

    ?问题一:var命令发生了“变量提升”现象,即变量可以在声明之前使用,值为undefined。这不符合先声明变量后使用的逻辑。

  先举个小例子来说明一下JavaScript中的变量提升

//var声明
console.log(foo); // 输出undefined
var foo = 2;


//let声明
console.log(bar); // 报错ReferenceError
let bar = 2;
//Uncaught ReferenceError: bar is not defined

 

  ES5中只有全局作用域和函数作用域,也会造成一些问题。

  ?问题二:变量作用域的不明确,导致变量泄漏。

function f(){
    if(true){
        var eg = "hello";
        console.log(eg,"if内部");  //"hello" if内部
    }
    console.log(eg,"fn内部");//"hello" fn内部
}
f() 
 console.log(eg);//报错,因为这个变量只在函数作用域中声明,也只能在函数作用域中使用

  从上面代码可以看出,在函数中内部的if语句中声明一个变量eg,尽管egif语句之外没有声明,但是在函数作用域中使用var命令,变量被提升到函数作用域中,所以也能被整个函数访问。这段代码中的变量泄漏是指if语句块内部声明的变量会在块外部被访问的情况。

 

  ?问题三:内层变量可能会覆盖外层变量

var tmp = new Date();

function f() {
  console.log(tmp);
  if (false) {
    var tmp = 'hello world';
  }
}

f(); // undefined

  从上述代码的意思是if语句块内外部各声明了一个tmp变量,但是函数执行后,输出的结果是undefined。原因在于变量提升,导致内层的tmp变量覆盖外层的tmp变量。  

  ES6中为了解决这些问题,新增let命令,让我们来看看let命令是怎么样发挥作用的。


二、let命令

  let命令存在一些特性:

  • 不存在变量提升
  • 暂时性死区
  • 不允许重复声明

不存在变量提升

在问题一举的例子中,可以看到,使用let命令声明变量时,在声明变量前使用变量会报错,let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则就报错。

 

暂时性死区

只要块级作用域中存在let命令,它所声明的变量就绑定在这个区域内,不再受外部的影响。总之,在使用let命令声明变量之前,该变量都是不可用的。

 

不允许重复声明

//报错
function fn(){
let a= 10;
let a = 1;
}

三、块级作用域

  为了解决上面的问题,ES6还新增块级作用域。let实际上为JavaScript新增了块级作用域。


四、const命令

const声明的一个只读变量。一旦声明,常量的值就不能改变。这意味着,一旦声明就需要马上赋值,只声明不赋值就会报错

const foo;
// SyntaxError: Missing initializer in const declaration

const也是只在声明所在的会计作用域中使用有效,变量不提升,也存在暂时性死区。

const的本质,不是保证变量的值不变,而是变量指向的那个内存地址所保存的数据不得改动