ES6解构赋值(一)对象解构

在ES5中,开发者们为了从对象和数组中获取特定数据并赋值给变量,编写了许多看起来同质化的代码

let options = {
    repeat: true,
    save: false
};
// 从对象中提取数据
let repeat = options.repeat,
save = options.save;

这段代码从options对象中提取repeat和save的值,并将其存储为同名局部变量,提取的过程极为相似

如果要提取更多变量,则必须依次编写类似的代码来为变量赋值,如果其中还包含嵌套结构,只靠遍历是找不到真实信息的,必须要深入挖掘整个数据结构才能找到所需数据

所以ES6添加了解构功能,将数据结构打散的过程变得更加简单,可以从打散后更小的部分中获取所需信息

对象结构:

对象字面量的语法形式是在一个赋值操作符左边放置一个对象字面量

let node = {
    type: "Identifier",
    name: "foo"
};
let { type, name } = node;
console.log(type); // "Identifier"
console.log(name); // "foo"

在这段代码中,node.type的值被存储在名为type的变量中;node.name的值被存储在名为name的变量中

【解构赋值】

到目前为止,我们已经将对象解构应用到了变量的声明中。然而,我们同样可以在给变量赋值时使用解构语法

let node = {
    type: "Identifier",
    name: "foo"
},
type = "Literal",
name = 5;
// 使用解构来分配不同的值
({ type, name } = node);
console.log(type); // "Identifier"
console.log(name); // "foo"

在这个示例中,声明变量type和name时初始化了一个值,在后面几行中,通过解构赋值的方法,从node对象读取相应的值重新为这两个变量赋值

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

解构赋值表达式的值与表达式右侧(也就是=右侧)的值相等,如此一来,在任何可以使用值的地方都可以使用解构赋值表达式

let node = {
    type: "Identifier",
    name: "foo"
},
type = "Literal",
name = 5;
function outputInfo(value) {
    console.log(value === node); // true
}
outputInfo({ type, name } = node);
console.log(type); // "Identifier"
console.log(name); // "foo"

调用outputlnfo()函数时传入了一个解构表达式,由于JS表达式的值为右侧的值,因而此处传入的参数等同于node,且变量type和name被重新赋值,最终将node传入outputlnfo()函数

[注意]解构赋值表达式(也就是=右侧的表达式)如果为null或undefined会导致程序抛出错误。也就是说,任何尝试读取null或undefined的属性的行为都会触发运行时错误

【默认值】

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

let node = {
    type: "Identifier",
    name: "foo"
};
let { type, name, value } = node;
console.log(type); // "Identifier"
console.log(name); // "foo"
console.log(value); // undefined

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

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

let node = {
    type: "Identifier",
    name: "foo"
};
let { type, name, value = true } = node;
console.log(type); // "Identifier"
console.log(name); // "foo"
console.log(value); // true

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

【为非同名局部变量赋值】

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

let node = {
    type: "Identifier",
    name: "foo"
};
let { type: localType, name: localName } = node;
console.log(localType); // "Identifier"
console.log(localName); // "foo"

这段代码使用了解构赋值来声明变量localType和localName,这两个变量分别包含node.type和node.name属性的值。type:localType语法的含义是读取名为type的属性并将其值存储在变量localType中,这种语法实际上与传统对象字面量的语法相悖,原来的语法名称在冒号左边,值在右边;现在值在冒号右边,而对象的属性名在左边

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

let node = {
    type: "Identifier"
};
let { type: localType, name: localName = "bar" } = node;
console.log(localType); // "Identifier"
console.log(localName); // "bar"

在这段代码中,由于node.name属性不存在,变量被默认赋值为"bar"

【嵌套对象解构】

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

let node = {
    type: "Identifier",
    name: "foo",
    loc: {
        start: {
            line: 1,
            column: 1
        },
    end: {
        line: 1,
        column: 4
    }
}
};
let { loc: { start }} = node;
console.log(start.line); // 1
console.log(start.column); // 1

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

更进一步,也可以使用一个与对象属性名不同的局部变量名

let node = {
    type: "Identifier",
    name: "foo",
    loc: {
        start: {
            line: 1,
            column: 1
        },
        end: {
            line: 1,
            column: 4
        }
    }
};
// 提取 node.loc.start
let { loc: { start: localStart }} = node;
console.log(localStart.line); // 1
console.log(localStart.column); // 1

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值