1. 数组的解构赋值

基本用法

let [a, b, c] = [1, 2, 3];

let [a,,c] = [1,2,3];

let [a,...b] = [1,2,3]; // a=1; b=[2,3]

// set 结构也可以
let [x, y, z] = new Set(['a', 'b', 'c']);

// Iterator 接口的也可以
function* fibs(){
  yield 1;
  yield 2;
  yield 3;
  yield 4
}

let [first, second, third] = fibs();
third // 3

默认值
let [a=2] = [1];

若值为全等 undefined, 则才为默认值
let [a=2] = [undefined]; // a=2
let [a=2] = [null]; //a = null
let [a=2] = null; // 报错, 如果模式不是数组, 因为会两边不匹配
let [a=2] = undefined; // 报错

若默认值是一个表达式, 那么这个表达式是 惰性求值, 只有用到的时候才会求值
function f(){
  console.log('fffff'); // 这里不会执行
}
let [a=f()] = [1];
a; // 1

// 相当于执行了下面
if( [1][0] === undefined ){
  a = f();
}else{
  a = 1;
}

2. 对象的解构赋值

let {a=3} = {a: 1};
a; // 1

其实相当于:
let {a: a=3} = {a: 1};
// 有点类似于下面的写法
let _temp = {a: 1};
let a = _temp.a || 3;

解构赋值给空数组和空对象

let [a=3] = {} // ?会报错: Uncaught TypeError: undefined is not a function
let {a=3} = [] // 正确 a = 3;

下面的两种写法是一样的, 数组元素是按次序, 变量的取值由它对应的属性名决定。
let {a, b} = {a: 1, b: 2}
let {b, a} = {a: 1, b: 2}

如果变量名与属性名不一致, 写成下面这样, a 是匹配的模式, c 才是变量
let {a:c} = {a: 1, b: 2}
c; //1

说明对象的解构赋值是下面形式:
let {a, b} = {a: 1, b: 2};
// 等价于下面
let {a:a, b:b} = {a: 1, b: 2}

对象也可以进行嵌套
let {a: [{b}, c]} = {a: [{b: 2}, 3]}

a; // undefined
b; // 2
c; // 3

嵌套赋值例子:
let obj = {};
let arr = [];

( {a: obj.q, b: arr[0]} = {a: 1, b: 2} );
obj; // {q: 1}
b; // [2]

解构也可以指定默认值, 也是必须 === undefined
let { a=3 } = {a: 1};
a; //1

let { a=3 } = {a: null};
a; //null

let {a=4} = {a: undefined};
a; // 4

如果解构失败,变量的值等于undefined
let {a} = {b: 2};
a; // undefined

如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错。
// 报错
let {foo: {bar}} = {baz: 'baz'};
相当于:
let _temp = {baz: 'baz'};
{bar} = _temp.foo;
bar = _temp.foo.bar;

已经声明的变量用于解构赋值, 会将 {x}理解成一个代码块 而不是一个语句, 所以要有括号
let x;
{x} = {x: 1}; // Uncaught SyntaxError: Unexpected token =

let x;
({x} = {x: 1}); // 正确

{foo} = {foo: 1}; // 若不用let 也是正确的, foo 直接挂载到 window 下

3. 字符串的解构赋值
// 字符串转换成 类似数组
const [a,b] = 'hello';
a; // h
b; // e

// 字符串类似对象, 它有一个length 的属性
let {length : len} = 'hello';

4. 数值和布尔值的解构赋值
数值和布尔值都会转好成 包装对象

// 相当于s = 123.toStirng
let {toString: s} = 123;

// 相当于 s = true.toString
let {toString: s} = true;

解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。
由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。

let {a: 1} = null; // error
let {a: 1} = undefined; // error

5. 函数参数的解构赋值
function add([x, y]){
  return x + y;
}

add([1, 2]); // 3
相当于 [x, y] = [1, 2];

对于 map
// [5, 10]
[1, 2].map( (a) => a *5 );

// [3, 7]
[[1,2], [3,4]].map( ([a,b]) => a+ b )

函数参数的解构也可以使用默认值。

// 只有当传递的参数为undefined 或不传参数的时候, 才会执行 {a, b} = {a: 1, b: 3}
function move({a, b} = {a: 1, b: 2}){
return [a,b]
}
move({a: 3, b: 4}); // [3, 4]; 等价 {a, b} = {a: 3, b: 4}
move({a: 3}); // [3, undefined]; 等价 {a, b} = {a: 3}
move({}); // [undefined, undefined]; 等价 {a, b} = {}
move([]); // [undefined, undefined]; 等价 {a, b} = []
move(null); // 报错; 等价 {a, b} = null
move(); // [1, 2]; 等价 {a, b} = {a: 1, b: 2}
move(undefined); // [1, 2]; 等价 {a, b} = {a: 1, b: 2} // 同上面道理
function move({x = 0, y = 0} = {x: 100, y: 200}) {
return [x, y];
} move({x: 3, y: 4}); // [3, 4]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [100, 200]

undefined就会触发函数参数的默认值。
[1, undefined, 3].map( (a = 2) => a ); // [1, 2, 3]

6. 圆括号的问题
使用圆括号的情况

赋值语句并且非模式部分,可以使用圆括号。
({ p: (d) } = {p: 3}); // 正确, 这里d是非模式, p是模式, 最后 d = 3
let ({ p: (d) } = {}); // 错误, 因为是声音语句

[(b)] = [3]; // 正确, 说明这个b是非模式部分, 有点类似于 [0:(b)] = [3], 直接这么写会报错
({(a)} = {a: 3}); // 错误, 说明是这么执行 {(a): a} = {a: 3}; 括号加在了 a的模式部分

7.用途

1) 交换变量的值
let x=1;
let y=2;
[x,y] = [y,x];

2) 从函数返回多个值
function f(){
  return {
    a: 1,
    b: 2
  }
}

let {a, b} = f();

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

3) 函数参数的定义
function f([x, y, z]){
  console.log(arguments[0]); // [1,2,3]
  console.log(x, y, z);
}
f([1,2,3]);

function f({x, y, z}){
  console.log(arguments[0]); // arguments[0] 其实就是 {x: 1, y:2, z: 3}
  console.log(x, y, z); // x = 1, y = 2, z = 3;
}
f({x: 1, y: 2, z: 3});

4) 提取JSON数据
let o = {
  a: 1,
  b: 2
}

let {a, b} = o;

5) 函数参数的默认值
function f({x = 2, y = 3}){
  console.log(x, y);
}
f({});
f(); // error, 必须至少传入空对象, 否则会报错

6)遍历Map结构
var map = new Map();
map.set('first', 'hello');
map.set('second', 'world');

for(let item of map){
  console.log(item); // item 分别输出 ["first", "hello"], ["second", "world"]
}

所以可以写成:
for(let [key, value] of map){
  cnosole.log(key, value);
}

// 获取key 的值
for( let [key] of map){
  console.log(key);
}

// 获取value 的值
for( let [, value] of map){
  console.log(value);
}

7)输入模块的指定方法
const {a, b} = require('./test2')
import {a, b} from './test2';

变量的解构赋值--ES6的更多相关文章

  1. 03 | 变量的解构赋值 | es6

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

  2. es6之变量的解构赋值

    es5中通常我们声明变量都是以下的方式: var a = 10; var b = 20; var c = 30; //或者 var a = 10,b = 20,c = 30; //或者 var arr ...

  3. ES6 继续 变量的解构赋值

    春节放假这几天,感觉跟梦一样,瞬间就过去了.现在上班的前几天,都感觉有点不真实,不过看到口袋里的钱,就知道,是真真实实的度过了这个假期. 现在得开始重新工作了: 变量的解构赋值 ES6 允许按照一定模 ...

  4. ES6学习笔记之变量的解构赋值

    变量的解构赋值 ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构. 数组的解构赋值 以前,为变量赋值,只能直接指定值: 1 2 3 var a = 1; var b = 2; ...

  5. es6分享——变量的解构赋值

    变量的解构赋值:ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). 以前的写法: var a = 1; var b = 2; es6允许的写法 ...

  6. ES6 变量的解构赋值

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

  7. ES6 - 变量的解构赋值学习笔记

    变量的解析赋值 数组的解析赋值 es6允许按照一定的模式,从数组和对象中提取值,对变量进行赋值,这就称为解构. var a = 1; var b = 2; var c = 3; //在es6中允许写成 ...

  8. ES6学习之变量的解构赋值

    前言:什么是ES6?ECMAScript 6(简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了.其中相比较于ES5新增了诸多的特性,并且ES6可转换为ES5的语法.- ...

  9. es6笔记(3) 变量的解构赋值

    基本概念 本质上是一种匹配模式,只要等号两边的模式相同,那么左边的变量就可以被赋予对应的值. // 以往定义接个变量的时候,需要这样 var a = 1, b = 2, c = 3; // 使用ES6 ...

随机推荐

  1. 【leetcode 简单】第四十一题 Excel表列序号

    给定一个Excel表格中的列名称,返回其相应的列序号. 例如, A -> 1 B -> 2 C -> 3 ... Z -> 26 AA -> 27 AB -> 28 ...

  2. 蓝色简洁的企业cms网站权限后台管理模板——后台

    链接:http://pan.baidu.com/s/1pKUqbBd 密码:nink

  3. spring-boot 属性定义和配置bean

    自定义bean属性 1.定义bean属性 // 通过@ConfigurationProperties加载properties文件内的配置, // 通过prefix属性指定properties的配置的前 ...

  4. 关于linux系统如何实现fork的研究(二)【转】

    转自:http://www.aichengxu.com/linux/7166015.htm 本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 引言 前一篇关于li ...

  5. ahttp

    # -*- coding: utf-8 -*- # @Time : 2018/8/20 14:35 # @Author : cxa # @File : chttp.py # @Software: Py ...

  6. 判断Selenium加载完成

    How do you make Selenium 2.0 wait for the page to load? You can also check pageloaded using followin ...

  7. 大数据系列之Hadoop框架

    Hadoop框架中,有很多优秀的工具,帮助我们解决工作中的问题. Hadoop的位置 从上图可以看出,越往右,实时性越高,越往上,涉及到算法等越多. 越往上,越往右就越火…… Hadoop框架中一些简 ...

  8. PlantUML——3.Graphviz的安装

    官网:http://www.graphviz.org/Home.php   由于plantuml使用Graphviz来生成相关图形(只有序列图可以不依赖它),其它图形都需要, 因此得安装它,否则生成图 ...

  9. Linux 用户篇——用户管理的配置文件

    一.用户管理之配置文件的重要性 在Linux系统中,用户账户的相关信息是存放在相关配置文件中.而Linux安全系统的核心是用户账号,用户对系统中各种对象的访问权限取决于他们登录系统时用的账户,并且Li ...

  10. 几个python one-liner

    生成斐波那契数列的前10个数,从1开始.若生成前n个,改为range(n-2).代码很简单: List = reduce(lambda x, y: x + [x[-1] + x[-2]], range ...