ES6 解构

解构

ES6 新增了解构( destructuring ),它按照一定模式,从数组和对象中提取值,对变量进行赋值,这是将一个数据结构分解为更小的部分的过程。

对象解构

let { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"

let { bar, foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
默认值

当你使用解构赋值语句时,如果所指定的本地变量在对象中没有找到同名属性,那么该变量会被赋值为 undefined 。

let node = {
        type: "Identifier",
        name: "foo"
    };
let { type, name, value } = node;
console.log(type);    // "Identifier"
console.log(name);    // "foo"
console.log(value);    // 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
赋值给不同的本地变量名
let node = {
        type: "Identifier",
        name: "foo"
    };
let { type: localType, name: localName } = node;
console.log(localType);     // "Identifier"
console.log(localName);     // "foo"

type: localType 这种语法表示要读取名为 type 的属性,并把它的 值存储在变量 localType 上。该语法实际上与传统对象字面量语法相反,传统语法将名称放在冒号左边、值放在冒号右边;而在本例中,则是名称在右边,需要进行值读取的位置则被放在了左边。

数组解构

数组解构的语法看起来与对象解构非常相似,只是将对象字面量替换成了数组字面量。数组解构时,解构作用在数组内部的位置上,而不是作用在对象的具名属性上。

let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3

let [ , , third] = ["foo", "bar", "baz"];
third // "baz"

let [x, , y] = [1, 2, 3];
x // 1
y // 3

只要等号两边的模式相同,左边的变量就会被赋予对应的值

剩余项

使用 ... 语法来将剩余的项目赋值给一个指定的变量

let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]

let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []

let colors = ["red", "green", "blue"];
let [...clonedColors] = colors;
clonedColors   // ["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

字符串解构

字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。

let {length : len} = 'hello';
len // 5

参数解构

当 JS 的函数接收大量可选参数时,一 个常用模式是创建一个 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
});

很多 JS 的库都包含了类似于此例的 setCookie() 函数。在此函数内, name 与 value 参 数是必需的,而 secure 、 path 、 domain 与 expires 则不是。此处虽然无须列出一堆额外的具名参数。但无法仅通过查看函数定义就判断出函数所期望的输入。参数解构能够更清楚地标明函数期望输入。它使用对象或数组解构的模式替代了具名参数。

function setCookie(name, value, { secure, path, domain, expires }) { // 设置 cookie 的代码
}
setCookie("type", "js", {
    secure: true,
    expires: 60000
});

解构参数在没有传递值的情况下类似于常规参数,它们会被设为 undefined 。同样参数解构也可以设置默认值。

用途

互换两个变量的值
let a = 1, b = 2;
[a, b] = [b, a ];
console.log(a);     // 2
console.log(b);     // 1

简洁,易读,语义清晰。

从函数返回多个值
// 返回一个数组

function example() {
  return [1, 2, 3];
}
let [a, b, c] = example();

// 返回一个对象

function example() {
  return {
    foo: 1,
    bar: 2
  };
}
let { foo, bar } = example();

如果函数要返回多个值,我们只能将它们放在数组或对象里返回。有了解构赋值,取出这些值就非常方便。

提取 JSON 数据
let jsonData = {
  id: 42,
  status: "OK",
  data: [867, 5309]
};

let { id, status, data: number } = jsonData;

console.log(id, status, number);
// 42, "OK", [867, 5309]
函数参数的定义
// 参数是一组有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]);

// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});

解构赋值可以方便地将一组参数与变量名对应起来。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容

  • 前面的话 我们经常定义许多对象和数组,然后有组织地从中提取相关的信息片段。在ES6中添加了可以简化这种任务的新特性...
    sunnyghx阅读 736评论 0 0
  • 参考:ES6入门(阮一峰)解构:解构与构造数据截然相反。 例如,它不是构造一个新的对象或数组,而是逐个拆分现有的对...
    IceLake阅读 3,867评论 0 2
  • 注意:iOS所有图标的圆角效果由系统生成,给到的图标本身不能是圆角的。 桌面图标 (app icon)for iP...
    独居焚香阅读 468评论 0 3
  • Mixed martial arts (MMA) is a full-contact combat sport t...
    怪物办公室阅读 282评论 0 0
  • 如果诊断的目的是为了治愈的话。 如果本身能够治愈为什么要冠上诊断后的标签久久不能抬头与治愈。
    朱周阅读 191评论 0 0