ES6 let/const

2/25/2019 前端基础ES6

# let 声明

  • let和作用域 ES6引入了let,用let声明变量,解决了JavaScript没有块级作用域的问题 作用域简单的来说,就是一套寻找变量的规则,用于确定在何处以及如何查找变量。说直白点:这些变量在哪里?它们存储在哪里?编译器如何找到它们?ES6代码之前,只有全局作用域或函数作用域。

当一个块或函数嵌套在另一个函数时,就发生了作用域嵌套。如下代码所示,就有三个嵌套作用域:

function foo(a){
    var b =a*2;
    function bar (c){
        console.log(a,b,c)
    }
    bar (b*3)
}
foo(2)//2,4,12
  1. 全局作用域,其中有一个标识符:foo
  2. foo创建的函数作用域,其中有三个标识符:a,barb
  3. bar创建的函数作用域,其中有一个标识符:c

如何理解全局作用域和函数作用域呢,使用var声明变量时,如果在函数外声明,就是全局变量,任何函数都可以进行使用,这就是全局作用域查找。如果在函数内使用var声明变量,就是函数作用域查找,只能在函数内部进行访问,外部不能进行访问,如下段代码所示:

var a = 12; // 全局作用域都能访问
function myFunction() {
    alert(a); // alerts 12
    var b = 13;
    if (true) {
        var c = 14; // 函数内部可以访问
        alert(b); // alerts 13
    }
    alert(c); // alerts 14
}
myFunction();
alert(b); // alerts undefined

因为变量b是在函数内进行声明的,因此函数执行完后,由于垃圾数据回收机制的存在,引擎认为函数执行完了,变量应该进行销毁释放。

如果你在函数内的b标识前忘记写了var关键词,引擎就会自作聪明,在函数外全局作用域为你自动声明变量b,这样在函数外就能访问b变量了(全局作用域)。

因此使用var进行声明时,如果一不小心,你就会声明一个全局作用域的变量,更糟糕的情况还有可能污染一个同名的变量,因此产生的BUG就很难查找。

以下这个例子会更加明显,也是开发者经常会出现的问题,i变量会绑定到外部作用域(函数或全局作用域),污染整个外部作用域:

for (var i = 0; i < 10; i++) {
    console.log(i); //依次输出1到9
}
console.log(i);//10

# let 与 var 的区别

  • 不能重复定义
  • 变量不提升
  • 块级作用域
let a = 0;
let a = 1; // SyntaxError
var a = 0;
var a = 1;
alert(a); // alerts 1
//在嵌套作用域里进行重新定义变量,虽然变量名相同,但是不是同一变量,如下段代码所示:
var a = 1;
let b = 2;
function myFunction() {
    var a = 3; // different variable
    let b = 4; // different variable
    if(true) {
        var a = 5; // overwritten
        let b = 6; // different variable
        console.log(a); // 5
        console.log(b); // 6
    }
    console.log(a); // 5
    console.log(b); // 4
}
myFunction();
console.log(a);
console.log(b);

函数声明和变量声明都会被提升(使用var声明变量,let声明变量将不会被提升)。函数首先会被提升,然后才是变量提升。

最后提交: 7/15/2022, 10:42:12 AM