引言

数组和对象就像一个 “压缩包”。

在需要单独引用数组中的某一个元素时,解构赋值可以很方便的完成这个任务,它可以将数组和对象整体 “解压缩” 到一堆变量上,不同的元素 (属性) 对应不同的变量。

数组的解构赋值

基本用法

使用数组中的元素,最直接的办法是通过数组的索引。

const user = ['kylin', 18, '女'];const name = user[0];const age = user[1];const gender = user[2];console.log(name, age, gender); // kylin 18 女

数组的解构赋值会简化这个过程。

const user = ['kylin', 18, '女'];const [name,  age,  gender] = user; // 就好像将数组元素分别解压到 3 个常量上console.log(name, age, gender); // kylin 18 女

模式匹配

数组的解构赋值有两种模式匹配情况,一种是 “等号” 两侧的模式一致。

const user = ['kylin', [[18], ['女']]];// const [name, age, gender] = user; // 这种模式是解构不出来的const [name, [[age], [gender]]] = user;console.log(name, age, gender); // 成功输出:kylin 18 女

另一种是 “等号” 两侧模式一致,但忽略了某些元素值,相当于不完全解构 。

const [js, php] = ['JavaScript', 'php', 'Java'];console.log(js, php); // const [js, php] = ['JavaScript', 'php', 'Java'];console.log(js, php);

默认值

有时候,数组的元素比定义的变量 (常量) 要少,但赋值并不会报错,多出来的变量会默认为 undefined 。

const [name, age, gender] = ['kylin', 18];console.log(name, age, gender); // kylin 18 undefined

也可以给多出来的变量默认值,当数组元素少于变量个数时,变量将采用默认值。

const [name, age, gender = '女'] = ['kylin', 18];console.log(name, age, gender); // kylin 18 女

数组元素值是显式的 undefined 时,变量也采用默认值。

const [name, age, gender = '女'] = ['kylin', 18, undefined];console.log(name, age, gender); // kylin 18 女

...rest 模式

数组的解构赋值可以配合 ...rest 模式使用。

const [name, age, ...rest] = ['kylin', 18, '女', '2020', 'JS'];console.log(name, age); // kylin 18console.log(rest); // rest是个数组  ["女", "2020", "JS"]

...rest 模式这里是一个数组,它由什么组成?代码中,先将 'kylin' ,'18' 两个数组元素 “解压到” 常量 'name' 和 'age' 上,然后将剩余的数组元素 '女' ,'2020' ,'JS' 打包到 rest 中,形成一个数组。

需要注意的问题

等号右侧任何可遍历的结构都可以用数组解构 (具备 Iterator 接口) 。

例如,字符串,Set 和 Map 结构。

const [k, y, l, i, n] = 'kylin';console.log(k, y, l, i, n);  // k y l i nconst [name, age, gender] = new Set(['kylin', 18, '女']);console.log(name, age, gender); // kylin 18 女const [[name, age], [gender, year]] = new Map([['kylin', 18], ['女', '2020']]);console.log(name, age, gender, year); // kylin 18 女 2020

等号右侧不是数组,不可以用数组解构赋值 。

// 报错,x is not iterable,x = {} ,null ,100 ....const [name] = {}; const [name] = null;const [name] = undefined;const [name] = true;const [name] = 100;

还有一个比较隐秘的小问题容易忽视。

有时候可能需要一个定义好的变量,随后对它进行解构赋值。

let name;let age;const user = ['kylin', 18] //  没有分号,与下一行的'[ ,(' 等字符连接,导致 arr 初始化失败[name, age] = user; // 报错了console.log(name, age);

如果加上分号就没问题了。

let name;let age;const user = ['kylin', 18];[name, age] = user;console.log(name, age); // kylin 18

一些使用方式

用逗号过滤不想要的元素。

const [name, age, , year] = ['kylin', 18, '女', '2020'];console.log(name, age, year); // 过滤了 女 ,kylin 18 2020

字符串有一个 split() 方法,将字符串用指定的分隔符分割成数组。

const word = 'hello kylin';const say = word.split(' ');console.log(say); // ['hello', 'kylin']

配合数组的解构赋值,是个不错的主意。

const word = 'hello kylin';const [say, name] = word.split(' ');console.log(say, name); // hello kylin

数组的解构赋值可以交换变量。

let firstName = 'kylin';let lastName = 'kun';[firstName, lastName] = [lastName, firstName];console.log(firstName, lastName); // kun kylin

数组的解构赋值还可以给对象增加属性。

const user = {};const person = ['Kylin', 18];[user.name, user.age] = person;console.log(user.name, user.age); // Kylin 18

可以配合 for...of 和 Map 使用。

const user = new Map();user.set("name", "Kylin");user.set("age", "18");for([key, val] of user) {  console.log(`${key}: ${val}`);}/* * name: kylin * age: 18*/

适用于函数返回数组的情况,也适用于函数参数是数组的情况。

function getUser(){  const user = ['kylin', 18, '女'];  return user;}const [name, age, gender] = getUser();console.log(name, age, gender); // kylin 18 女// -------------------------function getUser([name, age]) {  console.log(`姓名:${name},年龄:${age}`);}getUser(['kylin', 18]); // 姓名:kylin,年龄:18

配合 Object.entries() 方法。

Object.entries() 会把对象的键值转换用数组的形式表现出来。

const user = {  name: 'kylin',  age: 18};const info = Object.entries(user);console.log(info); // [['name', 'kylin'], ['age', 18]]

Object.entries() 方法可以和数组的解构赋值一起使用。

const user = {  name: 'kylin',  age: 18};const info = Object.entries(user);const [[keyName, name], [keyAge, age]] = info;// name:kylin, age:18console.log(`${keyName}:${name}, ${keyAge}:${age}`);

或者直接用 for...of 遍历。

const user = {  name: 'kylin',  age: 18};const info = Object.entries(user);for(const [key, val] of info) {  console.log(`${key}: ${val}`);}/* * name: kylin * age: 18*/

解构一个日期。

const [full, year, month, day] = /^(dddd)-(dd)-(dd)$/.exec('2020-03-28');console.log(full); // 2020-03-28console.log(year); // 2020

对象的解构赋值

基本用法

对象也可以进行解构赋值。

const user = {  name: 'kylin',  age: 18};const {name, age} = user;console.log(name, age); // kylin 18

注意等号左边是 {} ,而不是 [] 。

模式匹配

对象的属性顺序无关紧要。

const user = {  name: 'kylin',  age: 18};const {age, name} = user;console.log(name, age) // kylin 18

定义的变量名必须和对象的属性名一致,否则,变量名会是 undefined ,取不到任何值。

const user = {  name: 'kylin',  age: 18};const {n, age} = user;console.log(n, age); // undefined 18

不过,可以自定义一个变量简写,来简化后期用的变量名。

const user = {  myEnglishName: 'kylin',  age: 18};const {myEnglishName: name, age} = user;console.log(name, age); // kylin 18if (name === 'kylin') {  // ...} else {  // ...}

此时的 name 是变量,而 myEnglishName 不是变量。

默认值

对象的解构赋值同样支持默认值。

const user = {  name: 'kylin',  age: 18,  hobby: 'football'};const {name, age, work = 'student', hobby = 'food', gender, year = '2020'} = user;console.log(name, age, work, hobby, gender, year); // kylin 18 student football undefined 2020

对象中存在的属性,定义的变量就不会使用默认值,而不存在的属性,定义的变量依然是 undefined ,如果有默认值,就使用默认值 。

简写变量同样可以取得默认值。

const user = {  name: 'kylin',  age: 18,  hobby: 'football'};const {name: n, age: a, work: w = 'student', hobby: h = 'food', gender: g} = user;console.log(n, a, w, h, g); // kylin 18 student football undefined

...rest 模式

与数组的解构不同,对象的解构遇到 ...rest 模式时,会将剩余的属性收集为一个对象集合。

const user = {  name: 'kylin',  age: 18,  hobby: 'football'};const {name, ...rest} = user;console.log(name, rest); // kylin {age: 18, hobby: "football"}

需要注意的问题

在 JavaScript 中 {} 是个代码块,把它放在等号左侧,会导致报错。

let name;let age;const user = {  name: 'kylin',  age: 18}; {name,age} = user;console.log(name, age);

这种情况需要加上 () 告诉 JavaScript 不是代码块。

let name;let age;const user = {  name: 'kylin',  age: 18}; // 注意分号,参考上面的数组({name, age} = user);console.log(name, age); // kylin 18

一些使用方式

设置一个配置文件,然后传入函数。

const opts = {  width: 200,  height: 100,  speed: 1};function render({name = '盒子', width: w = 50, height: h = 20, speed}) {  console.log(`移动宽度为 ${w} ,高度为 ${h} 的 ${name} , 速度:${speed}`);}render(opts); 

嵌套的解构也可以。

const user = {  basic: {    id: '001',    username: 'kylin',    password: '123456'  },  work: ['JavaScript', 'Node'],  score: 88,  public: true};const my = {  basic: {    id,    username: u,    password: p  },  work: [js, node],  score,  public,  gender = '女'} = user;console.log(id, u, p, js, node, score, public, gender );// 001 kylin 123456 JavaScript Node 88 true 女

总结

解构赋值,我认为是一个非常好的功能,如果能熟练运用它,可以提高工作效率。

相关阅读:《了解 JavaScript 的 rest参数与扩展运算符 (ES6)》

文章中的图片来源于网络,若有侵权行为,请在后台与我联系。

exec 直接赋值_了解 JavaScript 解构赋值相关推荐

  1. 最详细ES6教程_变量的解构赋值

    最详细ES6教程_变量的解构赋值 数组的解构赋值 基本用法 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). 以前,为变量赋值,只能直接指定 ...

  2. JavaScript 解构赋值

    文章目录 JavaScript 解构 数组解构 分配默认值 交换变量 跳过项 将剩余元素分配给单个变量 嵌套解构赋值 参考文档     在本教程中,您将借助示例了解 JavaScript 解构赋值. ...

  3. JavaScript解构赋值

    JS解构赋值 1. 什么是解构赋值 ? 2. 数组的解构赋值 2.1) 数组解构赋值的默认值 2.2) 数组解构赋值的应用 类数组中的应用 交换变量的值 3. 对象的解构赋值 3.1) 对象解构赋值的 ...

  4. [JavaScript]解构赋值详解

    文章目录 概念 数组解构 声明分别赋值 解构默认值 交换变量值 解构函数返回的数组 忽略返回值(或跳过某一项) 赋值数组剩余值给一个变量 嵌套数组解构 字符串解构 对象解构 基础对象解构 赋值给新变量 ...

  5. ES6新特性_变量的解构赋值---JavaScript_ECMAScript_ES6-ES11新特性工作笔记006

    然后我们再看,变量的解构赋值. 可以看到按照一定的模式,从数组和对象中提取数据,以及对对应的变量进行赋值 被称为解构赋值. 可以看到上面 let[xiao,liu,zhao,song]=F4 相当于我 ...

  6. 一篇文章搞懂JavaScript解构赋值

  7. JavaScript系列之解构赋值

    文章の目录 一.解构赋值概述 二.解构赋值语法 三.描述 四.示例[解构数组] 1.变量声明并赋值时的解构 2.如果解构不成功,变量的值为undefined. 3.变量先声明后赋值时的解构 4.默认值 ...

  8. json解析 子类和父类同名属性如何赋值_想学变量的解构赋值?看完这一篇就够了...

    序言 ES6允许按照一定模式从数组和对象中提取值,然后对变量进行复制,这被称为解构(Destructuring) 数组的解构赋值 基本用法 像上面的例子,可以从数组中提取值,按照对应位置对变量赋值,这 ...

  9. [ES6] 细化ES6之 -- 变量的解构赋值

    变量的解构赋值 解构赋值是什么 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值 var/let [变量名称1,变量名称2,...] = 数组或对象 本质上,这种写法属于"模式 ...

最新文章

  1. oracle精度制的数据类型,ORACLE 中NUMBER 类型 低精度转换成高精度
  2. 最强轻量级目标检测yolo fastest
  3. halcon的算子清点:Chapter 7 :Image
  4. android跑步软件,手机跑步软件哪个好_安卓手机跑步记录软件_手机跑步app【最新】-太平洋电脑网...
  5. mongoDB3.0.2 升级操作
  6. Warning: POST Content-Length of 29328854 bytes exceeds the limit of 8388608 bytes in Unknown on line
  7. 远程桌面登录 Windows Server 2003时提示无权限
  8. mysql seconds_behind_master_MySQL中的seconds_behind_master的理解
  9. 基于JAVA+SpringMVC+MYSQL的学生成绩管理系统
  10. app 怎么通过jmeter 进行性能测试
  11. 基于socketserver实现并发的socket编程
  12. MySQL 怎么插入10天前的日期_Mysql笔记
  13. 学计算机的当大学老师,待遇那么低,研究那么苦,你为啥还去大学当老师?
  14. 百度给创新员工发2000w奖金........
  15. android 支付宝私钥加密,支付宝支付密钥RSA1升级到RSA2
  16. 保险核保、理赔|门诊住院发票识别||医疗单据医疗票据识别技术
  17. 深度学习之Deep Image CTR Model
  18. 饿了么美团外卖cps返利系统外卖返利公众号搭建cps系统小程序SaaS源码
  19. exit status 145: Ŀ¼���ǿյġ� exit s
  20. 怎么快速调节EDIUS中声音的淡入淡出?

热门文章

  1. win11资源管理器卡顿怎么办 Windows11解决资源管理器卡顿的步骤方法
  2. classcastexception异常_让你为之颤抖的Java常见的异常exception
  3. 前端命名规范_值得收藏的前端命名规范
  4. python基本内容讲解_Python命名约定基本内容解析
  5. mysql获取多张表中的数据_mysql之多表查询
  6. 1431.拥有最多糖果的孩z
  7. 可以随意更改规则的贪吃蛇(只要你懂,建议收藏)
  8. mfc之DDX_Control作用
  9. python循环三次跳出循环_Python3 跳出多重循环 for...else...
  10. 201609-1-最大波动