JavaScript ES6中的let、const解析

前端 · 2020-08-17 ·

ES 全称是 ECMAScript,它是由ECMA国际标准化组织,制定的一项脚本语言的标准化规范。

ES6 实际是一个泛指2015年以后的版本

why ES6?JavaScript语言本身有一些令人不满意的地方。

比如:

  • 变量提升特性增加了程序运行时的不可预测性
  • 语法过于松散,实现相同的功能,代码模式没有统一的思想。

1 let

ES6 中新增的用于声明变量的关键字

1.1 let 声明的变量只在所处于的块级作用域有效(之前有全局作用域和局部作用域)

    /*
    let 关键字就是用来声明变量的,
    let声明的变量只能够在其块级作用域{}可用
    */
    if (true) {
        let a = 20200817;
        console.log(a); // 20200817
        if (true) {
            let c = 20;
        }
        //console.log(c); // Uncaught ReferenceError: c is not defined
    }
    //console.log(a); // Uncaught ReferenceError: a is not defined
    /* 
    在一个{}中,使用let关键字声明的变量才具有块级作用域
    var 关键字是不具备这个特点的
    */
    if (true) {
        let letValue = 100;
        var varValue = 200;
    }
    //console.log(letValue); // Uncaught ReferenceError: letValue is not defined
    console.log(varValue); // 200

    // 防止循环变量变成全局变量,这是拥有块级作用的变量给我们解决了这个bug
    for (var i = 0; i < 5; i++) {

    }
    console.log(i); // 6
    for (let j = 0; j < 5; j++) {

    }
    //console.log(j); // Uncaught ReferenceError: j is not defined

1.2 不存在变量提升

   // 使用let关键字声明的变量没有变量提升,只能先声明再使用
    console.log(d); // Uncaught ReferenceError: Cannot access 'd' before initialization
    let d = 20;

1.3 暂时性死区

    /*
    使用let关键字声明的变量具有暂时性死区特性
    一旦在块级作用域中使用let关键字声明了这个变量num
    这个变量num就会和这个块级区域{}整体绑定
    在当前的区域当中使用num变量和全局作用域中的num变量没有任何关系
    let 关键字什么的num变量具有暂时性死区特性
    */
    var num = 123;
    if (true) {
        console.log(num);
        let num;
    }

1.4 老生常谈

// 关键点在于变量i是全局的,函数执行时输出的都是全局作用域下的i值;
var arr = [];
for (var i = 0; i < 2; i++) {
    arr[i] = function() {
        console.log(i)
    }
}
arr[0](); // 2
arr[1](); // 2

// 可通过立即执行函数
// IIFE(立即执行函数)内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量。
var arr2 = [];
for (var i = 0; i < 2; i++) {
    (function(i) {
        arr2[i] = function() {
            console.log(i)
        }
    })(i);
}
arr2[0](); // 0
arr2[1](); // 1

// let声明的变量具有块级作用域,
// 在循环结束后形成了2个块级作用域
// 2个块级作用域中都有变量i,他们是互不影响的,他们处于2个不同的块级作用域中
var arr3 = [];
for (let i = 0; i < 2; i++) {
    arr3[i] = function() {
        console.log(i)
    }
}
arr3[0](); // 0
arr3[1](); // 1

2 const

作用:声明常量,常量就是值(内存地址)不能变化的量。

2.1 具有块级作用域

// 使用const 关键字声明的常量具有块级作用域
if (true) {
    const a = 10;
    if(true){
        const a =20;
        console.log(a); // 20
    }
    console.log(a); // 10
}
//console.log(a); //Uncaught ReferenceError: a is not defined

2.2 声明常量时必须赋初始值

//声明常量时必须赋初始值
const PI; //Uncaught SyntaxError: Missing initializer in const declaration

2.3 常量赋值后,值不能修改,其实是内存地址不可更改

// 基本数据类型
const PI = 3.14;
PI = 100; // Uncaught TypeError: Assignment to constant variable.

// 引用数据类型
const arr = [100, 200];
arr[0] = 'a';
arr[1] = 'b';
console.log(arr);
// 此时试图改变arr的存储地址,这个是不合法的
arr = ['c', 'd']; // Uncaught TypeError: Assignment to constant variable.

3 let、const、var的区别

  • 使用var 声明的变量,其作用域为该语句所在的函数内,且存在变量提升的现象
  • 使用let 声明的变量,其作用域为该语句所在的代码块内,不存在变量提升
  • 使用const 声明的常量,在后面出现的代码中不能再修改该常量的值(内存地址)
var  let const
函数级作用域 块级作用域 块级作用域
变量提升 不存在变量提升 不存在变量提升
值可修改 值可修改 值不可修改
上一篇:
%