• 数组解构
  • 对象解构
  • 声明与解构相关的问题
  • 解构与重复赋值
  • 按需解构
  • 默认值赋值
  • 解构参数

解构(destructuring):结构化赋值

解构通常被看作ES6的一个结构化赋值方法,可以通过解构将数组元素或者对象属性拆分出来,成为单个变量。并且在命名相同的情况下可以实现名称复用,以达到减少代码量的目的,解构的基本目的就是减少代码量。

ES6之前从数组中拆分元素然后赋值给变量怎么做?

 function foo(){
return [1,2,3];
}
var tmp = foo(),
a = tmp[0], b = tmp[1], c = tmp[2];
console.log(a, b, c); // 1 2 3

采用ES6的解构数组的代码:

var [a, b, c] = foo(); 

ES6之前从对象中拆分属性作为变量转码做?

 function bar(){
return {
x:4,
y:5,
z:6
}
}
var tmp = bar(),
x = tmp.x, y = tmp.y, z = tmp.z;
console.log(x, y, z); //4 5 6

ES6解构对象属性的代码:

 var {x:x, y:y, z:z} = bar(); //这行代码还可以简写:var {x, y, z} = bar();
console.log(x, y, z); //4 5 6

对象属性赋值模式:

看到上面的解构语法,第一个疑问就是数组和对象是通过什么方式将元素和属性值赋给变量的呢?背后的复杂逻辑就不再这里探讨,值得我们关注的是,表达式中的那个是变量名称,那个是元素或者属性的引用?当看到数组的解构时,还比较好理解:

var [a, b, c] = foo(); 

从示例中可以看到a, b, c是变量的名称,而它们实际上是通过中括号“[]”的数组索引将foo()方法执行方法的对应的索引的值,赋值给对应位置的变量。而这样我们就可以推断出,对象解构在解构表达中左边的“x:”表示的是对象的属性值引用,“x”是变量,简写的方式在示例的注释中已经写出来了,意思就是变量复用对象的属性名作为变量名。如果是要通过解构来声明全新的变量名呢?

let {x:bam, y:baz, z:bap} = bar();

这就是对象属性赋值模式,因为左边的结构很像一个对象,但是结构的语法却是从左向右赋值,不是对象自变量中的右边向左边的属性名赋值。

声明与解构相关的一些问题:

在通常的开发中,我们都喜欢将变量名称写在作用域的第一排,这种书写方式有时候甚至被写入开发手册中,作为开发代码的书写标准,这时候对象结构就需要加上小括号,避免“{}”被解析为一个块级作用域:

 var a, b, c, x, y, z;
[a, b, c] = foo();
({x, y, z} = bar()); // 对象解构时这种情况要记得写小括号

解构时可以使用计算属性:

比如需要解构对象中的属性添加到另一个对象中,可以使用计算属性的方式来实现:

 var which = "x",
o = {};
({[which]:o[which]} = bar());// 本质上同等与({x:0.x})
console.log(o.x); //

解构与重复赋值:

通过上面的一系列解构传值逻辑,重复使用解构对象的属性值就很简单理解了,看下面:

 var {s:m, s:n} = {s:10}; //重复使用s属性值分别赋给m, n
console.log(m, n);// 10 10

接着玩一些更复杂的重复赋值的解构:

 var {a:{x: X, x: Y},a} = {a: {x: 1}};
//分析:
// 第一步
// ({x: X, x:Y} = {x: 1}); a = {x:1};
// 第二部
// X = 1, Y = 1,

再来一个数组的重复赋值解构:

 var {a:X, a:Y, a:[Z]} = {a:[1]};
// 分析
// 第一步
// X = [1], Y = [1], ([Z] = [1]);
// 第二部
// Z = 1;
console.log(X,Y,Z); // [1] [1] 1
X[0] = 10;
Y.push(2);
console.log(X,Y,Z); // [10,2] [10,2] 1

通过上面这个示例也说明了解构出来的应用值类型的数据只是简单的引用赋值,不是克隆,一档有一个引用将其中的属性值修改,其他所有引用都会被作用到。

按需解构:

按下解构就是只解构想要的属性和元素,并且可以允许出现没有相匹配的属性和元素,这个对应的变量会被声明但没有赋值。

 var [,,c,d] = [1,2,3];
var {w,z} = {x:10,y:20,z:30};
console.log(c,d); // 3 undefined
console.log(w,z); // undefined 30

默认值赋值:

有了上面的不匹配现象,就让我想起了ES6给方法提供的默认参数,在解构中也可以实现默认值:

 var [a = 3, b = 6, c = 9, d = 12] = [1, 2, 3];
console.log(a, b, c, d); // 1 2 3 12
var {x, y, z, w = 50} = {x:10, y:20, z:30}
console.log(x, y, z, w); //10 20 30 50

解构参数:

起始本质上解构就是一种变量声明与赋值行为,所以这种操作当然也就可以被放到方法的参数里面来,这让传值变得非常方便,也省去了麻烦的参数类型的转换和拆解。

 function ([x,y]){
console.log(x,y);
}
foo([1,2]);// 1 2

形参作为变量接收,实参是被解构的对象。

最后来一个有意思的算法题,使用解构实现两个变量交换值:

 var a = 10, b = {value:"B"};
[a, b] = [b, a];
console.log(a, b); //{value:10} 10

最后可以综合的使用解构的这些语法来实现非常复杂的应用,比如解构默认值 + 参数默认值实现传参,嵌套默认:解构重组,详细可以参考《你不知道的JS》下卷P86~P90。

ES6入门三:解构的更多相关文章

  1. ES6入门教程---解构赋值和字符串扩展

    解构赋值: ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). 数组的解构赋值: 按照对应的顺序解构. var arr = [1,[2,3]]; ...

  2. es6学习笔记--解构赋值

    昨天学习了es6语法中解构赋值,解构赋值在声明中和函数传参提高了灵活性和便捷性,值得掌握该语法. 概念: ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构.   数组的解构 ...

  3. 关于ES6 的对象解构赋值

    之 前写了关于ES6数组的解构 现在 go on ; 解构不仅可以用于数组,还可以用于对象: 对象的解构和数组有一个重要的不同.数组的元素是按次序排列的,变量的取值是由他的位置决定的:而对象的属性没有 ...

  4. 【JS】325- 深度理解ES6中的解构赋值

    点击上方"前端自习课"关注,学习起来~ 对象和数组时 Javascript 中最常用的两种数据结构,由于 JSON 数据格式的普及,二者已经成为 Javascript 语言中特别重 ...

  5. ES6 变量的解构赋值

    数组的解构赋值     var [a,b,c] = [1,2,3];    左边是变量,右边是值,根据数据结构一一对应 只要等号两边的模式相同,左边的变量就会被赋予右边对应的值,必须模式相同 如果等号 ...

  6. [js高手之路]es6系列教程 - 解构详解

    解构通俗点说,就是通过一种特定格式,快捷的读取对象/数组中的数据的方法, es6之前,我们通过对象名称[键] 读取数据 var User = { 'name' : 'ghostwu', 'age' : ...

  7. ES6学习之 解构赋值

    最近看了一个vue的项目,发现作者大量使用了ES6的语法,包括async, Promise, Set, Map还有一些解构赋值, 才发现自己对于ES6的语法缺乏了总结和运用,看得有点艰难,所以重新学习 ...

  8. ES6 变量的解构

    默认值 let [foo = true] = []; foo // true let [x, y = 'b'] = ['a']; // x='a', y='b' let [x, y = 'b'] = ...

  9. es6变量的解构赋值学习笔记

    1. 解构赋值的规则是,只要等号右边的值不是对象,就先将其转为对象.由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错. let { prop: x } = undefin ...

随机推荐

  1. JavaScript如何封装插件

    什么是封装呢? 我的理解就是 把一个功能单独做成一个组件,就像做饺子,以前做饺子必须自己先用面粉做饺子皮,再做饺子馅,然后再手工包饺子,但是现在人们发明了自动包饺子机器,虽然机器里面的每一步骤和你自己 ...

  2. Java访问Oracle服务器

    Java访问Oracle服务器--orcl数据库---emp表 private static String driver =         "oracle.jdbc.driver.Orac ...

  3. Android数据存储的方式

    1. 内部存储    * 路径:  /data/data/包名/    * cache用于存储临时文件,系统内存不足时,清除缓存数据    * files用于存储重要的文件,要用户手动在应用程序列表清 ...

  4. vue 面试题(文章末尾还有其他链接)

    https://segmentfault.com/a/1190000016344599

  5. sysctl 命令

    sysctl命令 被用于在内核运行时动态地修改内核的运行参数,可用的内核参数在目录/proc/sys中.它包含一些TCP/ip堆栈和虚拟内存系统的高级选项, 这可以让有经验的管理员提高引人注目的系统性 ...

  6. k8s 管理机密信息

    一.启动应用安全信息的保护: Secret介绍: 应用启动过程中可能需要一些敏感信息,比如访问数据库的用户名密码或者秘钥.将这些信息直接保存在容器镜像中显然不妥,Kubernetes 提供的解决方案是 ...

  7. springboot-自定义异常处理器

    @Order(-1000) public class LocalExceptionResolver implements HandlerExceptionResolver { @Override pu ...

  8. 20190925 - 使 macOS 的 rm 命令删除到回收站的不完美办法

    今天使用 macOS 时,使用 rm 删除了一个不重要文件,为保证以后不删除重要文件,找到一个让 rm 命令更安全的办法. 使用 MacPorts 安装 rmtrash 命令. sudo port i ...

  9. hydra 使用

    Hydra介绍 Hydra是一个并行登录破解器,支持多种攻击协议.它非常快速和灵活,新模块易于添加.该工具使研究人员和安全顾问能够展示远程获得对系统未经授权的访问是多么容易. 它支持:Cisco AA ...

  10. JavaScript日期格式化处理

    /** * 获取年月,如:2018-08 */ export function getMonth () { return formatDate(new Date(), 'yyyy-MM') } /** ...