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

解构(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. vsCode安装todo插件

    使用过IDEA或者WebStrom的阿媛应该都知道他们都有一个TODO功能,方便我们跟踪注释,或者说是我们在项目代码里面所做的标记:但是如果你现在在使用vsCode,你会发现,没有TODO功能,幸好, ...

  2. 怎么彻底关闭卸载删除Cortana小娜进程,最简单

    原文地址:https://jingyan.baidu.com/article/90bc8fc8be67bcf653640cfa.html Win10中的Cortana是微软开发的一款个人AI助理,集聊 ...

  3. Camera 采集图像的方法

    使用 Camera 采集图像, 实现步骤如下: 需要权限: android.permission.CAMERA android.permission.WRITE_EXTERNAL_STORAGE // ...

  4. HttpClient提交数据

    用代码模拟浏览器的行为 * 轻量级的开源的框架 * Android在6.0 23 以后移除了httpclient ,所以开发中用的少了 * 编写步骤: 1. 打开浏览器 2. 输入网址 3. 敲回车 ...

  5. manager 实现进程之间的数据共享 list dict

    manager 能够实现进程之间的数据共享 (list,dict) 如果多个进程同事修改同一份共享数据,这个时候需要加锁,保证数据的准确性. (1) dict list 可以实现进程之间的数据共享 ( ...

  6. JSTL优点

    1. 在应用程序服务器之间提供了一致的接口,最大程序地提高了WEB应用在各应用服务器之间的移植. 2. 简化了JSP和WEB应用程序的开发.3. 以一种统一的方式减少了JSP中的scriptlet代码 ...

  7. php代码判断用户访问的当前协议是否为https

    public function isHttps() { if ( ! empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) ...

  8. nginx配置静态资源关闭访问日志

    location ~ .*\.(css|js|gif|png|jpg|jpeg|bmp|swf)$ { root $root_path; access_log off; }

  9. Springboot学习—CommandLineRunner接口(转载)

    前言 Spring boot的CommandLineRunner接口主要用于实现在应用初始化后,去执行一段代码块逻辑,这段初始化代码在整个应用生命周期内只会执行一次. 如何使用CommandLineR ...

  10. 2. bash基础

    通配符 通配符 功能说明 实例 * 匹配所有字符 ls *.o ? 匹配所有的当个字符 ls net??? [a-z] 匹配属于a到z范围集合内的一个字符 ls [a-i]* [...] 与方括号内的 ...