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. 超越icon font

    很久以前,我们如何使用图标? 1.切图 2.拼合(Sprites) 原始社会啊! 后来CSSGagagrunt-css-sprite 字体图标 相见不曾相识 Emoji绘文字 iconfont.cn直 ...

  2. ADO.NET中带参数的Sql语句的陷阱

    1.使用Parameter //利用构造函数方式 ,不推荐这样写 Parameter p =new Parameter("@id",值); cmd.Parameters.Add(p ...

  3. 2017ACM暑期多校联合训练 - Team 5 1001 HDU 6085 Rikka with Candies (模拟)

    题目链接 Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, s ...

  4. CMDB概述(一)

    浅谈ITIL TIL即IT基础架构库(Information Technology Infrastructure Library, ITIL,信息技术基础架构库)由英国政府部门CCTA(Central ...

  5. Xcode 获取本地IP

    // // // #define MAXADDRS 32 extern char *ip_names[MAXADDRS]; void InitAddresses(); void GetIPAddres ...

  6. hdu 5328 Problem Killer(杭电多校赛第四场)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5328 题目大意:找到连续的最长的等差数列or等比数列. 解题思路:1.等差等比的性质有很多.其中比较重 ...

  7. java校验身份证号码

    /** * 18位身份证校验,粗略的校验 * @author lyl * @param idCard * @return */ public static boolean is18ByteIdCard ...

  8. Tinyos 第三版Make系统

    1.make系统安装 cd tools ./Bootstrap ./configure make sudo make install 2.make系统结构 3.第三版Makerules文件部分解析 # ...

  9. JSON.parse()——json字符串转JS

    JSON 通常用于与服务端交换数据. 在接收服务器数据时一般是字符串. 我们可以使用 JSON.parse() 方法将数据转换为 JavaScript 对象. 语法 JSON.parse(text[, ...

  10. python模块分析之sqlite3数据库

    SQLite作为一种应用广泛的文件式关系型数据库,python操作sqlite主要有两种方式,原生SQL语句和ORM映射工具. SQLAlchemy连接SQLITE SQLAlchemy是一款优秀的p ...