解构是将一个数据结构分解为更小部分的过程。
一、对象解构
对象的属性值存储到本地变量。
let node = { type: "Identifier", name: "foo" }; let { type, name } = node; console.log(type); // "Identifier" console.log(name); // "foo"
说明:使用解析配合var、let、const声明变量时,必须初始化。
例如下面会报错。
let { type, name };
1、解构赋值
变量声明之后,使用解构表达式改变他们的值。
let node = { type: "Identifier", name: "foo" }, type = "Literal", name = 5; // 使用解构来分配不同的值 ({ type, name } = node); console.log(type); // "Identifier" console.log(name); // "foo"
说明:必须用圆括号包裹解构赋值语句,因为暴露的花括号会被解析为代码块语句。
2、默认值
使用解构赋值语句时,如果所指定的本地变量在对象中没有找到同名属性,那么该变量会被赋值为 undefined。
可以指定属性值不存在或为undefined时的默认值。
let node = { type: "Identifier", name: undefined }; let { type, name = "foo", value1, value2 = true } = node; console.log(type); // "Identifier" console.log(name); // foo console.log(value1); // undefined console.log(value2); // true
3、赋值给不同的本地变量名
给本地变量赋值时使用一个不同的名称,也可以给变量别名添加默认值。
let node = { type: "Identifier" }; //localType和localName为两个本地变量 let { type: localType, name: localName = "bar" } = node; console.log(localType); // "Identifier" console.log(localName); // "bar"
4、嵌套的对象解构
let node = { type: "Identifier", name: "foo", loc: { start: { line: 1, column: 2 }, end: { line: 1, column: 4 } } }; let { loc: { start }} = node; console.log(start.line); // 1 console.log(start.column); // 2 //为本地变量使用不同的名称 let { loc: { end: localEnd }} = node; console.log(localEnd.line);//1 console.log(localEnd.column); //4
二、数组解构
let colors = [ "red", "green", "blue" ]; let [ firstColor, secondColor ] = colors; //按数组的位置顺序赋值 console.log(firstColor); // "red" console.log(secondColor); // "green" let [,,thirdColor] = colors; //按数组指定元素赋值 console.log(thirdColor); // "blue"
1、解构赋值
与对象解构不同,不必将表达式包含在圆括号内。
let colors = [ "red", "green", "blue" ], firstColor = "black", secondColor = "purple"; [ firstColor, secondColor ] = colors; console.log(firstColor); // "red" console.log(secondColor); // "green"
互换变量值
let a = 1, b = 2; [ a, b ] = [ b, a ]; console.log(a); // 2 console.log(b); // 1
2、默认值
数组解构赋值同样允许在数组任意位置指定默认值。当指定位置的项不存在、或其值为undefined ,那么该默认值就会被使用。
let colors = [ "red" ]; let [ firstColor, secondColor = "green" ] = colors; console.log(firstColor); // "red" console.log(secondColor); // "green"
3、嵌套的解构
let colors = [ "red", [ "green", "lightgreen" ], "blue" ]; let [ firstColor, [ secondColor, thirdColor ] ] = colors; console.log(firstColor); // "red" console.log(secondColor); // "green" console.log(thirdColor); // "lightgreen"
4、剩余项
使用 ... 语法来将剩余的项目赋值给一个指定的变量。
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"
用concat()方法或剩余项都可以克隆数组。
var colors = [ "red", "green", "blue" ]; var clonedColors1 = colors.concat(); console.log(clonedColors1); //"[red,green,blue]" let [ ...clonedColors2 ] = colors; console.log(clonedColors2); //"[red,green,blue]"
三、混合解构
在对象与数组混合而成的结构中,提取需要的字段。
let node = { type: "Identifier", name: "foo", loc: { start: { line: 1, column: 1 }, end: { line: 1, column: 4 } }, range: [0, 3] }; let {loc: { start }, range: [startIndex] } = node; console.log(start.line); // 1 console.log(start.column); // 1 console.log(startIndex); // 0
四、参数解构
函数接收大量可选参数时,常用模式是创建一个 options 对象,其中包含了附加的参数,就像这样:
// options 上的属性表示附加参数 function setCookie(name, value, options) { options = options || {}; let secure = options.secure, path = options.path, domain = options.domain, expires = options.expires; // 设置 cookie 的代码 } // 第三个参数映射到 options setCookie("type", "js", { secure: true, expires: 60000 });
这种方法很有用,但无法仅通过查看函数定义就判断出函数所期望的输入。
参数解构提供了更清楚地标明函数期望输入的替代方案。它使用对象或数组解构的模式替代了具名参数。
function setCookie(name, value, { secure, path, domain, expires }= {}) { // 设置 cookie 的代码 }
说明:需要为第三个参数提供了一个空对象{}作为其默认值,否则只传前面2个参数时会出错。
参数解构的默认值
function setCookie(name, value, { secure = false, path = "/", domain = "example.com", expires = new Date(Date.now() + 360000000) } = {}) { // ... }