说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

【探秘ES6】系列专栏(六):解构赋值

HTML文档下载 WORD文档下载 PDF文档下载
新一代JavaScript标准ES6正式发布。【探秘ES6】系列专栏将一一剖析ES6的诸多新特性,让Web开发者对此有清晰全面的了解。本文为系列的第六篇,带你了解ES6的解构赋值。

ES6作为新一代JavaScript标准,已正式与广大前端开发者见面。为了让大家对ES6的诸多新特性有更深入的了解,Mozilla Web开发者博客推出了《ES6 In Depth》系列文章。CSDN已获授权,将持续对该系列进行翻译,组织成【探秘ES6】系列专栏,供大家学习借鉴。本文为该系列的第六篇。 

什么是解构赋值?

解构赋值可将数组的元素或对象的属性赋予给另一个变量,该变量的定义语法与数组字面量或对象字面量很相似。此语法非常简洁,相比于传统的属性访问方式,更加直观清晰。

在不使用解构赋值的情况下,通常我们这样访问数组中的元素:

var first = someArray[0];var second = someArray[1];var third = someArray[2];

使用解构赋值后,代码得到了极大的简化,同时可读性也更强:

var [first, second, third] = someArray;

除了个别特性,解构赋值的大部分特性在SpiderMonkey(Firefox的JavaScript引擎)中都已得到支持,详见 bug 694100。

解构数组与其可迭代性

上面的例子为我们展示了解构赋值在数组中的运用,其基本语法形式为:

[ variable1, variable2, ..., variableN ] = array;

这只是将变量1到变量N分配到数组相应的元素中。当然,如果想在同一时间对变量进行声明,可以在赋值前增加相应的关键字:var,let或const:

var [ variable1, variable2, ..., variableN ] = array;let [ variable1, variable2, ..., variableN ] = array;const [ variable1, variable2, ..., variableN ] = array;

事实上,变量一词用的并不准确,因为解构赋值同样可以用于数组嵌套的情况(注意:左右两侧的格式应保持一致):

var [foo, [[bar], baz]] = [1, [[2], 3]];console.log(foo);// 1console.log(bar);// 2console.log(baz);// 3

此外,左侧的变量列表还可以一种包含连续逗号的形式跳过右侧对应的值:

var [,,third] = ["foo", "bar", "baz"];console.log(third);// "baz"

ES6中,提供了一种将右侧多余的值以数组的形式赋值给左侧变量的语法——“rest“模式:

var [head, ...tail] = [1, 2, 3, 4];console.log(tail);// [2, 3, 4]

无论是访问数组外还是数组中不存在的元素,都会得到相同的结果:undifined:

console.log([][0]);// undefinedvar [missing] = [];console.log(missing);// undefined

注意,数组赋值模式的解构赋值,同样也可迭代:

function* fibs() {  var a = 0;  var b = 1;  while (true) {    yield a;    [a, b] = [b, a + b];  }}var [first, second, third, fourth, fifth, sixth] = fibs();console.log(sixth);// 5

解构对象

在对象中使用解构赋值,允许你为对象的不同属性绑定变量名。这种情况下,解构赋值的左侧部分类似一个对象字面量,对象中是一个名值对的列表,属性名称位于名值对内冒号左侧,变量名称位于名值对内冒号右侧,每一个属性都会去右侧对象中查找相应的赋值,每一个值都会赋值给它对应的变量:

var robotA = { name: "Bender" };var robotB = { name: "Flexo" };var { name: nameA } = robotA;var { name: nameB } = robotB;console.log(nameA);// "Bender"console.log(nameB);// "Flexo"

当属性名称和变量名称相同时,可如下简写:

var { foo, bar } = { foo: "lorem", bar: "ipsum" };console.log(foo);// "lorem"console.log(bar);// "ipsum"

就像嵌套数组可用于解构赋值一样,嵌套对象也可用于解构赋值,并且两种语法还可以结合在一起使用:

var complicatedObj = {  arrayProp: [    "Zapp",    { second: "Brannigan" }  ]};var { arrayProp: [first, { second }] } = complicatedObj;console.log(first);// "Zapp"console.log(second);// "Brannigan"

使用解构赋值访问对象中未定义的属性,将会得到undifined:

var { missing } = {};console.log(missing);// undefined

为对象的属性命名,但未对其声明(缺少var、const或let关键字),会抛出一个语法错误:

{ blowUp } = { blowUp: 10 };// Syntax error

这是因为,JavaScript的语法规定引擎对语句进行解析,需以块语句为开头(例如,{console}便是一个有效的块语句)。解决的办法是将整个表达式包裹在一对括号中:

({ safe } = {});// No errors

非对象、数组、迭代的解构类型

当我们尝试对null或undefined使用解构赋值时,将会抛出一个类型错误:

var {blowUp} = null;// TypeError: null has no properties

但是,对于其他原始类型如:布尔量,数字或字符串等则可以运用解构赋值,并得到undifined:

var {wtf} = NaN;console.log(wtf);// undefined

对于这种情况,你可能会感到很意外。但原因其实很简单,这是因为使用对象赋值模式时,被解构的值必需能够转换成一个对象(object)。大多数的类型都可以转换为一个对象,但null和undefined却并不能被转换。当使用数组赋值模式时,其值必须有一个迭代器。

默认值

对于值和属性未定义的数组与对象,你仍可以运用解构赋值的方式为其设定默认值:

var [missing = true] = [];console.log(missing);// truevar { message: msg = "Something went wrong" } = {};console.log(msg);// "Something went wrong"var { x = 3 } = {};console.log(x);// 3

(编者注:此功能在Firefox上目前只实现了前两种情况,而第三种并未实现。见bug932080。)

解构的实际应用

函数参数定义

作为开发人员,我们经常把一个对象用作函数的参数。这个对象具有很多的属性,以便暴露出更多便于我们使用的API,从而无需迫使我们的开发者去记住大量独立参数的顺序。我们对参数对象使用解构赋值,这样,在访问对象属性时,便可以避免重复调用这一参数对象,示例代码如下:

function removeBreakpoint({ url, line, column }) {  // ...}

这是来自Firefox开发工具JavaScript调试器(在JavaScript中执行)中的代码简化片断。我们发现这种模式是极好的。

配置对象参数

对前面的例子进行扩展,若我们正在对对象的属性进行解构赋值,那么我们仍旧可以为其赋予默认值。这是十分有用的,尤其是当我们打算配置对象或是对象的属性已经有了合理的默认值。例如,jQuery中的AJAX函数需要一个配置对象作为其第二参数,可以改写如下:

jQuery.ajax = function (url, {  async = true,  beforeSend = noop,  cache = true,  complete = noop,  crossDomain = false,  global = true,  // ... more config}) {  // ... do stuff};

这样就避免了为配置对象中的每个属性重复:var foo = config.foo || theDefaultFoo(编者注:不幸的是,在Firefox中,对象简写语法中的默认值仍旧不可使用,详情见bug932080的最新更新。)

ES6迭代协议

ECMAScript6中还定义了一项迭代的协议,在这个系列的前面我们已经谈到过。当你遍历 Maps(一个ES6非标准库),会得到一系列的[key,value]。我们可以对这些[key,value]运用解构的方式,从而方便地访问它们:

var map = new Map();map.set(window, "the global");map.set(document, "the document");for (var [key, value] of map) {  console.log(key + " is " + value);}// "[object Window] is the global"// "[object HTMLDocument] is the document"

只遍历key:

for (var [key] of map) {  // ...}

或只遍历value:

for (var [,value] of map) {  // ...}

多返回值

你可以通过数组的形式返回多个值,并对其解构赋值:

function returnMultipleValues() {  return [1, 2];}var [foo, bar] = returnMultipleValues();

或者,返回的值为一个对象,用解构赋值的方式对其进行命名:

function returnMultipleValues() {  return {    foo: 1,    bar: 2  };}var { foo, bar } = returnMultipleValues();

与上面两种模式相比,下面这种模式就显得过于繁琐:

function returnMultipleValues() {  return {    foo: 1,    bar: 2  };}var temp = returnMultipleValues();var foo = temp.foo;var bar = temp.bar;

或着使用连续风格的传递(continuation passing style):

function returnMultipleValues(k) {  k(1, 2);}returnMultipleValues((foo, bar) => ...);

从CommonJS的模块中导入接口名

不使用ES6模块了吗?仍使用CommonJS的模块?没问题!当导入一些CommonJS的模块时,非常常见的情况是模块的接口功能比你实际需求的多许多。通过解构的方式,你可以明确你需要的那部分,并且可以防止多余的接口名污染你的命名空间:

const { SourceMapConsumer, SourceNode } = require("source-map");

(如果你使用ES6模块,你应当知道类似的语法可用于声明导入。)

结语

所以,就如你所看到的那样,在很多独立细小的方面,解构赋值都非常有用。在Mozilla,关于它的使用我们积累了大量的经验。十年前Lars Hansen将JS的解构赋值模式引入Opera,随后Brendan Eich将他引入Firefox。并在Firefox2中得以应用。

之前,我们说ES6将会改变你写JavaScript的方式。将这些新的特性和微小的改进结合起来,它终将会影响你工作中的每一个项目。这是一场以进化的方式发起的革命。

当然,这是团队努力取得的成果。在这里,特别感谢Tooru Fujisawa (arai)和Arpad Borsos (Swatinem)作出的杰出贡献。关于浏览器的支持方面,Chrome对解构的支持正在开发中,无疑其他浏览器会及时支持。至于现在,如果你想在Web上使用解构,则需要使用 Babel或 Traceur。

原文链接:ES6 In Depth: Rest parameters and defaults

本译文遵循Creative Commons Attribution Share-Alike License v3.0 

相关阅读:

【探秘ES6】系列专栏(一):ES6简介

【探秘ES6】系列专栏(二):迭代器和for-of循环

【探秘ES6】系列专栏(三):生成器

【探秘ES6】系列专栏(四):模版字符串

【探秘ES6】系列专栏(五):剩余参数和默认参数

欢迎加入CSDN前端交流群:218126086,进行前端技术交流。  

从下拉菜单设计细节看Amazon对用户体验的把握 Chartboost美女CEO:40人团队服务3亿移动玩家 Distimo:新晋开发者想让产品得到关注越来越难 OpenFeint绝迹后,开源项目OpenKit继续前进 美FDA通过搜索引擎和社交平台预警药品副作用 挖坟三星“眼球追踪技术”背后的技术团队 为什么开发者热衷在Stack Overflow上查阅API文档? Facebook推新News Feed 欲造就“个性化报纸” 女神程序员的一天:暴力测试social爬虫代码 2013IBM云存储路线图:更快,更简单,更安全 二战大数据故事:数学家、物理学家、概率论击败德国潜艇 软件定义网络服务商Pertino B轮融资2000万 Scringo社交组件,让你的应用“热闹”起来! Android开发必备:Eclipse 4.2 SR2版本发布 32场!2013年360HTML5校园行首站告捷 移动周报:不做内容,只钻技术的快播 一周消息树:中国开源发展缓慢的“病因” 百度应用引擎BAE正式开放 新增支持Node.js CloudVelocity,下一个VMware? Buffer创始人谈开发:先验证,后编程! 谷歌可穿戴式产品再度来袭:会说话的鞋子 未来Chrome OS或取得Android般成功 云落地@北京,北京市北斗公共平台或开放API? GitHub再遭攻击 主要服务中断约一小时 移动开发者将有望拥有.app域名使用权 微信将推“游戏中心”?移动互联网入口圈地加剧 美国航空公司首次开放API 并举办“黑客马拉松”编程大赛 谷歌数据中心设计的10条“黄金法则” GitHub时代:为什么我们都在开源 VMware发布Horizon Suite 三款应用打包折扣低 TOP30+应用排行榜:二月份国内外综合榜单 我的主机总收到外面发的广告信息? 高分求助急!!! 见鬼了,我添加一个TServerSocket控件,然后编译出现:Declaration terminate incorrectly 有谁知道用哪款打印机比较好呢? 按钮BitBtn1上有图片,在图片上写字的问题。(在先给分!) cystal reports 8.5 english显示繁体问题,急,等待 Unix下用什么源代码检测工具比较好? 我的电脑出什么问题了?各位帮帮忙 界面导航如何分类? 怎样得到本机的网卡号??? %¥#问个小问题,知道的都来抢分啊 谁知道哪儿有支持认证的SMTP组件下载? 有什么软件能查看PE文件的? ADO问题!!!! 100分求购最简单的串口程序!需要详细注释! 怎么给大家份呀?to wyz_csdn等(500分诚征wav 转换到MP3的源程序(VC++的例子)) 在directshow中,不知道怎样对播放的画面的亮度进行控制? 如果深愛的人要離開你,是變心還是死亡好一點?(讨论) 贴了二次为什么没有人指教? 戒水快两年了,如今回来看看,物不是人非啦 新手一问 关于datagrid 修改数据的问题,帮我看看,多谢 谁有这两本书,请帮忙发到我的邮箱里,100分相送 到底应该怎么办? 大家好,如何打开DLL文件? 建议成立一个程序员协会 关于IE中图片的保存 VB 语言支持问题 高分求李维《delphi5.xDELPHI5.X ADO/MTS/COM+高级程序设计》示例源码!!!! 请yangshu进来!给妳点分!!!倒分! 请教各位如何实现dbgrid中按住shift多选的问题? 请问把sql-server7中的数据文件copy出来行吗? 找不到类,请大家帮忙解决,谢谢 异常处理问题 怎样恢复被损坏的"本地用户和组" 小弟在线等待,一小问题,,大家来帮忙?? 求jsp树的原代码 最好是jsp+js+xml 执行效率要高。(从数据库中动态生成的)在线 关于多层结构中事务处理的问题. VB6.0升级到VB.NET的问题。 在ASP中使用ActiveX Control ADOTable表名如何在运行时“递进” 这样的待遇能招到人吗? 不好意思,问个技术问题。其他版实在没人气!只好来这问! 不爽,辞职,散分! 在线等待(100)往一个表的字段赋值,怎么不行啊! 急!在线等待! 如何把一个窗体内嵌到另外一个窗体的指定位置? 电源键设置问题 假设有一个变量CString str,调用str.GetBuffer(ncount);上面函数的参数应该为多少,才能取得缓冲中的全部字串值? 如何做局域网中的机子通讯 有关Enumerations的问题 血浆中co2能不能运到组织液中原题所问:co2的来源及其去向?来源一空有血浆,去向一空有组织液,是不是表明血浆中的co2可以进入组织液? 甲基营养菌 "小子安知壮士志哉"断句 英语翻译(一) (甲)良尝闲从容步游下邳圯上,有一老父衣褐,至良所,直堕其履圯下,顾谓良曰:“孺子,下取履!”良愕然,欲殴之.为其老,强忍,下取履.父曰:“履我!”良业为取履,因长跪履 细菌细胞的碳氮营养比为? “小子安知壮士志哉”的句意与司马迁 陈涉世家 中哪一句有异曲同工之妙? 宋太祖的杯酒释兵权是什么意思? 细菌细胞的碳氮营养比 柴草煤屑和可燃物堆放不合理,空气不流通可能引起什么后果?式分析原因! 为什么干电池长时间放置又有了电?3q 西欧走向联合的过程是怎样的?西欧走向联合的过程,起源于何事? 原料气 液化石油气 是什么?原料气是什么~我只知道原料气是液化石油气的一种原料,请问还有没有更深入,细致一点儿的分析呢? 该化合物该怎么命名?书上有命名为4-甲基-2-戊胺的? 二战后的时候,西欧走向联合始于神马领域?军事?经济?外交? 正常标准液化气瓶内装几公斤?一口灶正常连续使用每小时消耗几公斤气?每小时大概花费多少钱? 为什么没电的干电池长时间不用后还会生出电来. 西欧各国为什么要走向联合? 液化气气灶灶面材料哪种材料好?是钢化的玻璃板好?还是彩钢的好?哪个好,还有其他的材料的吗?我们家的液化气灶是彩钢的,一点都不好搞卫生,搞不干净,说是要用干的摸布擦一下,但是也不理 "四亚甲基二矾四胺"是什么东西啊知道那有卖的吗?这边的耗子成灾,没有办法,善哉善哉 在进行英语听力测试时,各考场的有线扬声器是同时开播,也是同时停播的,他们的连接方式是_____联,原因是它们 独立工作. 100克稀盐酸与足量的碳酸钙反应,生成的气体通入澄清的石灰水中,完全反应后可得到20克的白色沉淀,求该盐酸溶液的质量分数.【请用初三化学的算法,我们可没”学过“mol”这个单位】我想知 N'N-二(2-羟丙基)-N'N-四甲基己烯二胺有谁知道这个东西那里有销售的,或者是相关产品,以及类似的产品,只要是N'N-二(2-羟丙基)-N'N-四甲基这种类型的就可以了,(CH3)3[CH3CH(OH)CH2]N+-(CH2)6-+N(CH3)2[CH2CH(O 柴草燃烧是否符合质量守恒定律如题, 长者衰者而全存乎中而的意思. 所谓天诚者难测,而神者诚难明矣中而的意思 死而有知而的意思 共轭二烯烃和氢气有1,4加成的反应吗? 通其变,使民不倦;神而化之,使民宜之的意思 诚者 天之道也 诚之者 人之道也的意思 为什么宋太祖要杯酒释兵权? 一念通神是什么意思 诚者,天之道也;诚之者,人之道也.是啥意思 干电池用完了,为什么放置几天后又“生”电了呢? 幼学琼林里有一句“ 广钱固可以通神” 是什么意思?书上没的解释没看懂~他到底拿了人家的钱了吗? 诚者,天之道也;诚之者,人之道也 的意思 耳机的两个喇叭是串联还是并联 “神魔界有人情,精魅亦通世故”《西游记》刻画的众多神魔魅都具有人的情感.请举一例,具体说明这一特点 以下所列,哪些是以少胜多的著名战役?1.巨鹿之战 2.官渡之战 3.赤壁之战 4.淝水之战 A以下所列,哪些是以少胜多的著名战役?1.巨鹿之战 2.官渡之战 3.赤壁之战 4.淝水之战A.1234 B.124 C.234 D.134 用干柴草或煤气做燃料来煮饭,在这个过程中是什么能转化为热能 初读通语句,再读明大意,三读有感悟,四读有内涵,五读有启迪.这句话怎么理解?怎样用于文言文的讲解中我们要讲《山市》这篇课文,两个课时. 布雷顿森林体系和牙买加体系的不同点 农民在刚刚返青的麦田里烧柴草是干什么?请问是干什么 是为了保暖吗 柴草燃烧时释放的能量是生物能吗?如题、、还有吖——核能和地热能来自地球本身么? 班超字仲升 麻烦会数学的帮我看看这个arctan(1/6)=? 关于能源,下列说法正确的是:A:柴草燃烧时释放的能量是生物能 B核能和地热能来自地球本身 C动物体内葡萄C动物体内葡萄糖被氧化成CO2事热能转化为化学能的过程 牙买加体系与布雷顿森林体系相比有何不同? 考研数学三:arctan函数问题如图画蓝线部分,arctan(e^x)+arctan[e^(-x)]=π/2怎么算的? 1柴草燃烧放出的能量为生物能 2 核能地热能来自地球自身 判断正误与理由 班超,字仲升,扶风平陵人[1],徐令彪之少子也[2].为人有大志,不修细节,然内孝谨,居家常执勤苦,不耻劳辱.有口辩,而涉猎书传.永平五年[3],兄固被召诣校书郎[4],超与母随至洛阳[5]. 张良,韩信,萧何 怎么死的? 班超字仲升,扶冯平陵人,徐令彪之少子也 这是哪个文言文拜托勒```` 通过对布雷顿森林体系和牙买加货币体系的比较,你认为有什么变化? tan x 和 arctan x 之间有什么数学关系吗?比如是倒数这样的? 柴草燃烧的能量转换为什么是生物能转化为热能而不是生物能转化为热能? 后汉书 班超传:下列句子的句式特点相同的两项是( )( ) A.班超,字仲升,扶风平陵人 B.卿弟安在 C.兄固后汉书 班超传:下列句子的句式特点相同的两项是( )( )A.班超,字仲升,扶风平陵 做饭时若要时柴草燃烧更旺 可将柴草架空 其原因是? 韩信,张良,萧何谁最后死的?都咋死的? "小子安知壮士志哉"这句话的意思顺便把含有这句古文的文言文翻译出来. 柴草燃烧释放的是生物能吗 在进行英语听力测试时,各考场的有线扬声器是同时开播,也是同时停播的.它们的连接方式是___联,原因是它们___独立工作. “班超,字仲升…………小子安知壮士之志哉” 公司注册制度改革全球镜鉴——聚焦激发涉案金额240亿 “万家购物”网络传QE3“瘦身”延期 新兴市场仍需未雨背景资料:欧盟20年大事记公安部要求公安机关对暴力伤医行为坚决吉林松原10分钟内连发两次地震 东北世界勤俭日 请从身边小事做起浦发银行设立伦敦代表处巴西“张开双臂”欢迎中国企业投资卫计委:将逐步探索新农合跨省就医结报吉林松原前郭尔罗斯蒙古族自治县发生5华媒聚焦三中全会:中国新改革“分好蛋商务部回应“批评报道针对外资”:媒体中国建设银行落户卢森堡俄罗斯达吉斯坦共和国首府爆炸致1死8俄罗斯举行核遏制力突击战备演练精品画展向英国人展示中国水墨艺术的旧“被遗忘的天才”画展展现卡斯蒂廖内出未成年怀孕现象堪忧 每年700万少女巧克力为何充满魔力新华网:全方位织牢安全网 让困难群众一部极简香港经济史:客途秋恨的今非昔盘点小时候经常被同学欺负的十大明星香港足总:拖延时间正常,言语冲突或是谁土,我们管谁叫闰土好消息:谷歌有望今秋重返中国大陆市场1942年苏联“狙击女神”访美 遭记硬床对腰好不好?什么汽车没有雨刷器?谷歌无人驾驶汽车作为男性,如果有带薪产假的机会,你愿1944年苏军解放敖德萨 为占领巴尔常吃枸杞可祛病延缓衰老小师妹爱过令狐冲吗,还是止于兄妹或两揭秘李湘与谢娜争“一姐”反目成仇内幕意识流墨子打法解析 小地图助你做意识茅于轼对于「18亿亩耕地红线」的抨击安卓创始人Andy Rubin和他的感觉不如这个孩子内谁,领导,您,有(jia)匪(hu国家队比赛日皇马照常训练途家C轮融资close,融资额一亿美驾校考试科目三考试不及格的原因汇总
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘