资讯专栏INFORMATION COLUMN

ES6: 解构赋值(Destructuring)

CODING / 1767人阅读

摘要:一概念对象是属性的集合,从对象里取值,只能逐个取,而解构赋值表达式可以实现批量取值,赋值。赋值操作符等号两边的解构要一致才能正确赋值解构赋值表达式是赋值表达式的语法糖。三数组解构赋值数组的属性名称叫索引,表示的是位置。

一、概念

对象是属性的集合,从对象里取值,ES3/5只能逐个取,而解构赋值表达式可以实现批量取值,赋值。

// 数据对象person 
var person = {
    name: "john",
    age: 22
}

// ES5的方式:
var name = person.name,
    age = person.age;
    
// ES6解构赋值方式
var {name, age} = person;
二、对象解构赋值 2.1 语法
// 格式1:声明即赋值
var {key1: valName1=defaultVal1, key2: valName2=defaultVal2, ..., keyN: valNameN=defaultValN} = obj;

// 格式2, 先声明,后赋值。此时必须使用括号包裹整个赋值表达式
var valName1,valName2, ..., valNameN;
({key1: valName1=defaultVal1, key2: valName2=defaultVal2, ..., keyN: valNameN=defaultValN} = obj);

obj:表示数据源对象

key1:表示需要从数据源对象中取值的属性名称,如果和valName1同名,可以省略不写;

valName1:表示需要把获取的属性值赋值给的模板变量,即valNam1=obj[key1]

defaultVal1:表示obj对象不包含属性key1时指定的默认值,可选的。

所以用ES5的表示方式相当于:

var valName1 = obj[key1],
    valName2 = obj[key2],
    valNameN = obj[keyN];

如果key和valName的相同,可以简写为:

// 格式1:声明即赋值
var {valName1=defaultVal1, valName2=defaultVal2, ..., valNameN=defaultValN} = obj;

// 格式2, 先声明,后赋值。此时括号是必须的
var valName1,valName2, ..., valNameN;
({valName1=defaultVal1, valName2=defaultVal2, ..., valNameN=defaultValN} = obj);

大部分场景都是使用简写的方式。

假设有个对象dad:

// Object
var dad = {
    name: "john",
    age: 30,
    children: [
        {
            name: "Tom",
            age: 2
        },
        {
            name: "Jim",
            age: 1
        }
    ]
}

现在要把dad属性分别保存到变量name, age, children里:

// 格式1: 声明即赋值
var {name:name, age:age, children:children} = dad;
console.log(name); // john
console.log(age); // 30
console.log(children.length); // 2

// 格式2, 先声明,后赋值。此时括号是必须的,否则报语法错误
var name, age, children;
({name:name, age:age, children:children} = dad)

对应的简写格式:

// 格式1
var {name, age, children} = dad;
// 格式2
var name, age, children;
({name, age, children} = dad)
2.2 默认值

对于没有匹配到 或者匹配到的属性值为undefined的变量可以指定默认值。

dad.name = void 0; // dad定义见上例,
var { weight = "66kg", name="new name"} = dad; // dad没有定义weight属性
console.log(weight, name); // weight="66kg", name="new name"
2.3 动态属性名称

在上面的语法结构中

var {key1: valName1, key2: valName2, ..., keyN: valNameN} = obj;

其中key1,key2...keyN还可以是个变量,为了标识他们是变量而不是字面量,则需用用中括号包裹:

var key = "name";
var {[key]:val } = dad;
console.log(val); // "john"
key = "age";
({[key]:val } = dad);
console.log(val); // 30
2.4 小结

解构赋值的前提是同构,即左右两边的对象解构要一致;

对象解构赋值在绑定值时根据属性key(key的名称和结构位置)进行匹配的。赋值操作符(等号)两边的解构要一致才能正确赋值;

解构赋值表达式是赋值表达式的语法糖。

三、数组解构赋值

数组的属性名称叫索引,表示的是位置。所以跟对象的解构赋值相比语法上有些不同:

3.1 语法
// 语法格式1: 声明即赋值
var arr = [1, 2, 3, 4, 5, 6];
var [f, s, t] = arr;
// 语法格式2: 先声明,后赋值
var a, b, c;
[a, b, c] = arr;

console.log([f, s, t]) // [1, 2, 3]
console.log([a, b, c]) // [1, 2, 3]

数组解构赋值在绑定值时根据属性下标和进行匹配的。赋值操作符(等号)两边的解构要一致才能正确赋值,如果匹配不成功则取值为undefined。

3.2 跳跃式的赋值
var arr = [1, 2, 3];
var [,f,s] = arr; // f=2, s=3
3.3 获取数组剩下的元素

通过rest操作符(...)修饰变量可以实现获取数组剩下的元素:

var arr = [3, 4, 5, 6];
var [a, ...b] = arr;
console.log(b); // [4,5,6]

变量b获取数组arr剩余的元素,此时注意变量b必须放在最后,否则语法错误。如果没有剩余的元素,则为空数组,

var arr = [3];
var [a, b, ...c] = arr;
console.log(a) // 3
console.log(b) // undefined
console.log(c) // []
3.4 嵌套
// 获取二维数组的元素
var [[a00=1], [,a11]] = [[1, 2], [3, 4]];
console.log(`a00=${a00}, a11=${a11}`)

// 继续上面的例子,现在的需求是把dad对象里第2个孩子的属性保存到name,age变量里(这个写法就复杂了,结合了数组解构赋值和对象解构赋值):
var {children: [,{name, age}]} = dad;
console.log([name, age])

注意: 复杂的嵌套降低了可读性,需要权衡下是否要使用

3.5 数组也是对象

数组本身也是对象,数组的赋值解构也可以通过对象解构赋值的方式表示:

var arr = [1, 2, 3];
var {0:f, 1:s, 2:t} = arr; // 等价 var [f, s, t] = arr;
console.log([f, s, t]) // f=1, s=2, t=3

这样写确实麻烦哈,数组解构赋值是对数组对象解构赋值的的简化。他们的赋值匹配模式本质上是一样的

四、对非对象的变量进行解构
var {a } = 1, // undefined
    {b} = true, // undefined
    {c} = "a", // undefined
    {d} = null, // 类型错误
    {e} = undefined; // 类型错误

JS对这些基本类型数字,字符串,boolean都定义了对应的对象类型,在对这些类型的数据进行解构赋值操作时,会转成对应的对象类型。但是null, undefined却没有对应的对象类型,所有在运行时会报类型错误。

五、一些应用场景

总结一句话: 只要是发生赋值操作的场景都可以使用解构赋值表达式。

5.1 函数参数解构赋值
function log({title: tag = "Debug", message}) {
    console.log(`${tag}: ${message}`);
}

log({title: "Info", message: "This is a log message"})

要使用ES5实现上面的功能,大致如:

function log(option) {
    if(!option) option= {};
    var tag = option.title || "Debug",
        message = option.message;
    console.log(`${tag}: ${message}`);
}
log({title: "Info", message: "This is a log message"})

解构赋值用作函数的形参使得参数更加直观明了,并且可以赋值默认值。ES5的写法得读代码才能看到具体需要什么参数。

5.2 for-of语句

可以对集合元素进行解构操作,更方便循环体内取值。

for(var {name, age} of dad.children) {
    console.log(`name: ${name}, age: ${age}`)
}
5.3 函数返回值解构
// 方便正则取值
var url = "https://developer.mozilla.org/en-US/Web/JavaScript";
var parsedURL = /^(w+)://([^/]+)/(.*)$/.exec(url);
console.log(parsedURL); 
var [, protocol, fullhost, fullpath] = parsedURL;
console.log(protocol); // "https"
参考

MDN Destructuring assignment

ES6 In Depth: Destructuring

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/90284.html

相关文章

  • ES6系列文章 Destructuring

    摘要:解构是很重要的一个部分。解构代码如下上面的代码表示声明两个变量然后。实际业务中长方形的是不能没有值的。都算正常值的范畴。解构进阶解构时同时使用重命名和设置默认值的语法。若有,若没有属性,那么将赋值为。 Destructuring解构是ES6很重要的一个部分。和箭头函数、let、const 同等地位,解构可能是你日常用到最多的语法之一了。解构是什么意思呢?它是js 表达式,允许我们从数组...

    JiaXinYi 评论0 收藏0
  • [译] 最深刻而易懂的ES6解构教程

    摘要:被解构的数据项位于赋值运算符的右侧,可以是任何数组和对象的组合,允许随意嵌套。数组模式位于赋值运算符的左侧,被结构的数组在其右侧。 解构是ES6的新特性,用于从JavaScript对象和数组中提取数据,语法上比ES5所提供的更加简洁、紧凑、清晰。它不仅能减少你的代码量,还能从根本上改变你的编码方式。用的越多,你就会发现越多塑造数据和函数的方式,这些实现方式在过去几乎是不可能的。本文将深...

    AlphaGooo 评论0 收藏0
  • ES6部分方法点评(一)

    一直以来,我对ES6都不甚感兴趣,一是因为在生产环境中使用ES5已是处处碰壁,其次则是只当这ES6是语法糖不曾重视。只是最近学习react生态,用起babel来转换jsx之余,也不免碰到诸多用上ES6的教程、案例,因此便稍作学习。这一学习,便觉得这语法糖实在是甜,忍不住尝鲜,于是记录部分自觉对自己有用的方法在此。 箭头函数(Arrow Functions) 箭头函数是一个典型的语法糖,即创造了一种...

    weakish 评论0 收藏0
  • 深入理解 ES6解构赋值

    摘要:在可遍历的量中使用数组模型数组解构使用一个迭代器来获取数据源中的元素。所以,数组解构能够在上工作的迭代器总是按照元素插入的顺序将元素返回,所以上述的解构返回的结果总是相同的。 解构赋值(destructuring assignment)语法是一个Javascript表达式,这种语法能够更方便的提取出 Object 或者 Array 中的数据。这种语法可以在接受提取的数据的地方使用,比如...

    only_do 评论0 收藏0
  • es6 解构笔记分享

    摘要:只要某种数据结构具有接口,都可以采用数组形式的解构赋值。解构赋值允许指定默认值。默认值可以引用解构赋值的其他变量,但该变量必须已经声明。解构也可以用于嵌套结构的对象。 Es6 新增了destructuring(解构)语法糖, 我们快来了解一下: 可以按照一定的模式从数组/对象中提取值,为变量赋值数组解构 var a = 1; var b = 2; var c = 3; 可以写作: v...

    Hancock_Xu 评论0 收藏0

发表评论

0条评论

CODING

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<