ES6新技术之解构赋值语法

Understanding ECMAScript 6 解构赋值语法(Destructuring)是ES6新进的 使用 objects 和 arrays 的(可统称「结构对象」)更便捷的新语法,这种语法针对将结构对象的多个成员值一次读取(赋值给本地变量)出来,解构语法借用了对象字面量和数组字面量的语法。

本文部分内容择译自《Understanding ECMAScript 6

What

复合数据的使用

对象 和 线性集合数组 任务非常常见,它们都是有结构的 复合数据,经常需要从它们的结构中读取出数据(有多个)来。 Destructuring 是一种便捷的对象或数组的结构成员读取的新语法。

赋值操作的一种

解构赋值语法的核心(属)是「赋值」,它是赋值语句的一种;与一般单值赋值语句相对,它是一种复值赋值。单值赋值的模式是简单的——将一个字面值或者表达式值的估值后“赋给”一个符号变量,赋值是语法自动的;同样,结构赋值也有一定的模式,和语法自动(下面提供了各种详细):等号及两边(一边是变量,一边待的值)。结构赋值模式是:结构变量=结构实例,编译器自动的 将结构实例「解构」为子值逐个赋值给 结构变量 的子变量:

赋值模式: var = initializer 赋值语法:** variable = value;** 解构赋值语法:{variable,...} = object( or expressoin)

等号 等号右边:结构实例,或产生对象的表达式 等号左边:结构变量,由花括号或方括号,及本地变量列表

Why

对象 和 线性集合数组 复合数据的传统使用方式很繁琐:将字段一个一个读出到本地变量。如果你的对象或数组很大,数据字段很多,甚至是有多层嵌套时,读取数据就更麻烦,此时,解构语法则更显价值。

对象的解构

对象指对象实例,包含有非线性键值复合数据。

默认值

被解构的结构对象的成员不一定都存在(defined),解构语法支持对未定义的对象成员提供默认值( default values),并且当被解构的结构对象(赋值等号的右边)为 null or undefined 时,抛出异常。

let node = {
  type: "Identifier",
  name: "foo"
};
let { type, name, value = true } = node;

嵌套解构

解构语法支持访问任意嵌套层次的对象

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);
console.log(start.column);
// 1
// 1

声明式解构赋值

解构赋值最基本的使用形式是本地声明式:解构对象值到本地变量。声明式解构语法必须带有初始化器( initializer ,等号及右边的表达式),不然语法不完整:

let { type, name } = node; // fine
let { type, name } ; // syntax error

完整对象解构语法:{variable,...} = object( or expressoin) 等号 等号右边(结构实例):对象实例,或产生对象的表达式 等号左边(结构变量):花括号,及本地变量列表

解构赋值给现有变量

解构赋值语法也可对已经有的变量或对象属性进行赋值;注意赋值语句需要用括号,将其标识为表达式,不然结构变量(等号左边)会被认为是一个代码块。

let node = {
  type: "Identifier",
  name: "foo"
},
type = "Literal",
name = 5; // assign different values using destructuring 
({type,name} = node);
console.log(type); // "Identifier"
console.log(name); // "foo"

解构赋值表达式

解构赋值操作也可出现在表达式之中,取值是等号右边的结构对象(EM:这个不知道用啥,分开写不是更清楚明了吗?)

function outputInfo(value) {
  console.log(value === node);// true 
} 
outputInfo({ type, name } = node); // 这个将node将解构赋值给变量后,传入函数

赋值给不同本地变量

如果给 不同于对象成员名 的本地变量赋值,要加前缀,注意被赋值的本地变量在 冒号的右边

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

数组的解构

数组解构赋值语法模式与对象解构语法是相似的,只是使用了 数组字面量 语法,例如使用「方括号」替代「花括号」。另外,数组只有位置下标,所没有(也不用)属性来访问结构成员。

忽略不关心的成员

由于使用数组下标,你可以通过忽略下标位置直接读取某个数组成员值:

let colors = ["red", "green", "blue"];
let[, , thirdColor] = colors;
console.log(thirdColor); // "blue"

解构赋值给现有变量

与对象解构赋值不同,数组解构不需要括号,因为它的语法不会产生歧义:

let colors = ["red", "green", "blue"],
firstColor = "black", secondColor = "purple"; 
[firstColor, secondColor] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"

Rest Items

像新的ES6 函数技术支持 rest参数 一样,数组解构赋值语法也支持rest 项:将余下的数组成员赋给一个特定的变量:

let colors = ["red", "green", "blue"];
let[firstColor, ...restColors] = colors;

console.log(firstColor); // "red" 
console.log(restColors.length); // 2 
console.log(restColors[0]); // "green" 
console.log(restColors[1]); // "blue"

Rest 语法用于克隆数组

// cloning an array in ECMAScript 6 
let colors = ["red", "green", "blue"];
let [...clonedColors] = colors;

console.log(clonedColors); // "[red,green,blue]"

函数参数的解构

结构对象的值解构出来不但可以赋给本地(结构变量),也可以直接用来调用函数。

function setCookie(name, value, {secure, path, domain, expires }) { 
    // code to set the cookie 
}

let options = {
  secure: true,
  expires: 60000
};
setCookie("type", "js", options);

所谓 函数解构参数(destructured parameters),其实只是一般「本地声明式解构赋值」功能的一种灵活运用( 结构变量 用作参数,调用时进行结构赋值):

function setCookie(name, value, options) {
  let {	secure, path, domain, expires } = options; 
// code to set the cookie 
}
```
## 参考
- [https://exploringjs.com/es6/ch\_overviews.html#overview-entry-destructuring](https://exploringjs.com/es6/ch_overviews.html#overview-entry-destructuring)
- [http://es6.ruanyifeng.com/#docs/destructuring](http://es6.ruanyifeng.com/#docs/destructuring)
裸男
Nakeman.cn 2023 Build by Gatsby and Tailwind, Deploy on Netlify.