• ES6之对象解构



    ES6学习系列


    对象和数组字面量是JavaScript中两种最常用的数据结构,由于JSON数据格式的普及,二者已经成为语言中最重要的一部分。在代码中,我们经常定义很多对象和数组,然后从去提取相关的信息片段,ES6为简化这种任务引入了新特性:解构(destructuring assignment)。比如

    let a, b, rest;
    [a, b] = [10, 20];
    
    console.log(a);
    // expected output: 10
    
    console.log(b);
    // expected output: 20
    
    [a, b, ...rest] = [10, 20, 30, 40, 50];
    
    console.log(rest);
    // expected output: Array [30,40,50]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    执行结果如下
    在这里插入图片描述

    The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.

    为何使用解构功能

    在ES5以及早起版本中,开发者为了从对象和数组中获取特定数据并赋值给变量,需要编写许多看起来同质化的代码,比如

    let options = {
        repeat: true,
        save: false
    };
    // 从对象中提取数据
    let repeat = options.repeat,
        save = options.save;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    从options对象中提取repeat和save的值然后将其存储到同名的局部变量,提取的过程极其相似,如果需要提取更多变量,则必须一次编写更多类似的代码来为变量赋值,如果其中还包含嵌套解构,只靠遍历时找不到真实信息的,必须要深入挖掘整个数据结构才能找到所需数据。所以ES6为对象和数组都添加了解构功能,将数据结构打散的过程变得更加简单,可以从打散后更小的部分获取所需信息。

    对象解构

    对象解构的语法形式是在赋值操作符左边放置一个对象字面量,例如上面的示例修改如下

    let options = {
        repeat: true,
        save: false
    };
    // 从对象中提取数据
    let { repeat, save } = options;
    // true
    console.log(repeat);
    // false
    console.log(save);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这段代码中,options.repeat的值被存储在名为repeat的变量中,options.save的值被存储在名为save的变量中。
    如果使用var、let或const解构声明变量,则必须提供初始化程序(也就是等号右侧的值),否则会抛出如下异常:Uncaught SyntaxError: Missing initializer in destructuring declaration
    在这里插入图片描述

    解构赋值

    除了可以在定义变量时使用解构语法,也可以在定义变量之后通过解构语法修改值。

    let options = {
        repeat: true,
        save: false
    }, repeat = false, save = true;
    // 从对象中提取数据
    ({ repeat, save } = options);
    // true
    console.log(repeat);
    // false
    console.log(save);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里通过解构赋值的方法从options对象中提取值重新为变量赋值。但是要注意,一定要用一对小括号来包裹解构赋值语句。

    JavaScript引擎将一对开放的花括号视为一个代码块。而语法规定,代码块语句不允许出现在赋值语句左侧,添加小括号之后可以将块语句转化为一个表达式,从而实现了整个解构赋值的过程。

    解构赋值表达式的值与表达式右侧的值相等。如此一来,在任何可以使用值的地方都可以使用解构赋值表达式。想象一下给函数传递参数值的过程:

    let options = {
        repeat: true,
        save: false
    }, repeat = false, save = true;
    function output(value) {
        console.log(value === options);
    }
    output({ repeat, save } = options)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    调用output函数时传入一个解构表达式,由于JavaScript表达式的值为右边的值,因此此处传入的参数等同于options,且变量repeat和save被重新赋值,最终将options传入了output函数。

    解构赋值表达式(也就是右侧的表达式)为null或undefined会导致程序抛出错误。也就是说,任何尝试读取null或undefined的属性的行为都会触发运行时错误。
    在这里插入图片描述

    默认值

    使用解构赋值表达式时,如果指定的局部变量名称在对象中不存在,那么这个局部变量会被赋值为undefined,比如

    let options = {
        repeat: true,
        save: false
    };
    
    
    let { repeat, save, value } = options;
    // true
    console.log(repeat);
    // false
    console.log(save);
    // undefined
    console.log(value);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    这段代码额外定义了一个局部变量value,然后尝试为它赋值,然而在options对象上,没有对应名称的属性值,所以像预期中的那样最终它的值为undefined。

    当指定的属性不存在时,可以随意定义一个默认值,在属性名称后添加一个等号和相应的默认值即可。

    let options = {
        repeat: true,
        save: false
    };
    
    
    let { repeat, save, value = true } = options;
    // true
    console.log(repeat);
    // false
    console.log(save);
    // true
    console.log(value);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在上面的案例中,为变量value设置的默认值true,只有当options上没有该属性或者该属性位undefined时该值才生效。此处没有options.value属性,所以value使用了预设的默认值。

    如果对象中属性值为null,默认值是不会起效的。因为null在这里也是被视为有效值。
    在这里插入图片描述

    为非同名局部变量赋值

    在前面的案例中,解构赋值使用的都是与对象属性同名的局部变量,但如果希望使用不同命名的局部变量来存储对象属性的值。ES6中的扩展语法可以满足需求,这个语法与完整的对象字面量属性初始化程序很像。

    let options = {
        repeat: true,
        save: false
    };
    
    let { repeat: localRepeat, save: localSave } = options;
    // true
    console.log(localRepeat);
    // false
    console.log(localSave);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    这段代码使用了解构赋值来声明变量localRepeat和localSave,这两个变量分别包含options.repeat和options.save属性的值。 repeat: localRepeat语法的含义时读取名为repeat的属性并将其值存储在变量localRepeat中。这种语法实际上与传统对象字面量的语法相悖,原来的语法名称在冒号左边,值在右边。现在变量名称在冒号右边,而需要读取的位置在左边。

    当时用其他变量名赋值时也可以使用默认值,只需要在变量名后面添加等号和默认值即可。

    let options = {
        repeat: true,
        // save: false
    };
    
    let { repeat: localRepeat, save: localSave = true } = options;
    // true
    console.log(localRepeat);
    // true
    console.log(localSave);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    嵌套对象解构

    解构嵌套对象仍然与对象字面量的语法相似,可以将对象拆解以获取你想要的信息

    let options = {
        repeat: true,
        // save: false
        loc: {
            start: {
                line: 1, column: 1
            },
            end: {
                line: 1, column: 4
            }
        }
    };
    
    let { loc: { start } } = options;
    // 1
    console.log(start.line);
    // 1
    console.log(start.column);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这个示例中,我们在解构模式中使用了花括号,其含义时在找到了options对象中的loc属性后,应该深入一层继续查找start属性。在上面的解构示例中,所有冒号前的标识符都代表了对象中的检索位置,其右侧为被赋值的变量名:如果冒号后是花括号,则意味着要赋予的最终值嵌套在对象内部更深的层次中。
    也可以使用一个与对象属性名不同的局部变量名,比如

    let options = {
        repeat: true,
        // save: false
        loc: {
            start: {
                line: 1, column: 1
            },
            end: {
                line: 1, column: 4
            }
        }
    };
    
    let { loc: { start: localStart } } = options;
    // 1
    console.log(localStart.line);
    // 1
    console.log(localStart.column);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这个版本中,options.loc.start被存储在了新的局部变量localStart中,解构模式可以应用于任意层级深度的对象,且每一层都具备同等的功能。比如

    let options = {
        repeat: true,
        // save: false
        loc: {
            start: {
                line: 1, column: 1
            },
            end: {
                line: 1, column: 4
            }
        }
    };
    
    let { loc: { start: { line: localLine } } } = options;
    // 1
    console.log(localLine);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    由点汇聚成字的动效炫极了
    吉时利2604B系列数字源表,双通道,3A直流/10A脉冲
    直播录屏软件哪个好?什么软件可以录屏直播会议?
    SQL基本查询
    qt基础之d_ptr和q_ptr
    【Vue + Koa 前后端分离项目实战3】使用开源框架==>快速搭建后台管理系统 -- part3 权限控制+行为日志
    PMP考试提分必刷题
    项目部署上线
    第十章 异常
    论文阅读记录--关于水文系统的传递函数
  • 原文地址:https://blog.csdn.net/m0_37607945/article/details/127695588