解构就是ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值(只能用于数组,对象或迭代器)。如果解构不成功,则等于undefined,但不能赋值为undefined和null,因为undefined和null不属于数组或对象

1 数组的解构赋值

数组的解构赋值就是,按照数组元素的次序,取出它位置所对应的值,具体如下

var [a, b, c] = [1, 2, 3]; // a=1;b=2;c=3 相当于var a=1, b=2, c=3;
// 也可以用于let,const声明变量
let [x, y] = [4, 5] // x=4, y=5
// 位置对应
var [, , c] = [1, 2, 3]; // c=3
var [a, b, c] = [, 2,]; // a=undefined; b=2; c=undefined
// 嵌套数组 位置对应
var [a, [[b], c]] = [1, [[2], 3]]; // a=1; b=2; c=3
// ...表示剩下的所有值组成数组
var [a, ...b] = [1, 2, 3, 4];// a=1; b=[2,3,4];
var [a, ...b, c] = [1, 2, 3, 4]; //报错 Uncaught SyntaxError: Rest element must be last element in array
var [a, ...b] = [1]; // a=1; b=[];

解构只能用于数组,对象或迭代器,重要的事再重复一遍

当然,解构赋值也允许指定默认值

var [a=1] = []; // a=1
var [a, b=2] = [1]; // a=1, b=2
var [a, b=2] = [1, undefined]; // a=1; b=2
var [a, b=2] = [1, null]; // a=1; b=null;

思考一下,下面输出的结果,let声明时为什么报错

var [x=y,y=1]=[]; // x=undefined; y=1
let [x=y,y=1]=[]; // 报错 Uncaught ReferenceError: y is not defined

2 对象的解构赋值

上面提到了,数组的解构赋值是按照元素的位置来取值的,而对象的解构赋值是按照属性名来取值的

具体请看下面的例子

// 属性名和变量名一致
var {a, b} = {a:"aa", b:"bb"}; // a="aa"; b="bb"
var {a, b} = {b:"bb"}; // a=undefined; b="bb" 变量名a因为找不到属性名a的值
// 属性名与变量名不一致
var {a:c, b:d} = {a: "aa", b:"bb", c:"cc", d:"dd"}; //c="aa"; d="bb" 属性名为a,变量名为c
//对象嵌套数组
var o = {
p: ["hello", {y: "world"}]
};
// 也支持let和const
let {p:[x, {y}]} = o;// x="hello"; y="world"; 注意:p为属性名而不是变量名
// 对象嵌套对象
var o = {
p: {
q: {
x: "hello",
y: "world"
}
}
};
var {p:{q:{x, y}}} = o; // x="hello"; y="world"; 注意p,q为属性名而不是变量名

为已经声明的变量进行解构赋值,必须把整个表达式用小括号包裹,否则会报错,报错原因就是因为JavaScript语法通知解析引擎将任何以{开始的语句解析为一个块语句(例如,{console}是一个合法块语句)

var x;
{x} = {x:1}; // 报错 Uncaught SyntaxError: Unexpected token =
({x} = {x:1}); // x=1 let obj = {};
let arr = [];
({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true }); // obj={prop: 123}; arr=[true]; 注意区别属性名和变量名,foo,bar是属性名 obj.prop,arr[0]是变量名

3 解构赋值的用途

变换变量的值

var a = 1;
var b = 2;
[a, b] = [b, a]; // a=2; b=1;

函数取值

function func1(){
return [1, 2, 3];
}
var [a, b, c] = func1(); // a=1;b=2;c=3;
function func2(){
return {
a: "a",
b: "b"
}
}
var {a, b} = func2(); // a="a";b="b"

函数参数的定义及设置默认值

function func3({x, y, z}){
console.log(x+' '+y+' '+z);
}
func3({x:"x",y:"y",z:"z"});//x y z
function func4({x=1, y=2, z=3}){
console.log(x+' '+y+' '+z);
}
func4({});// 1 2 3

遍历Map结构

var map = new Map();
map.set('x','xx');
map.set('y','yy');
//获取键名和键值
for(let [key, value] of map){
console.log('key='+key+' value='+value);
//key=x value=xx
//key=y value=yy
} //获取键名
for(let[key] of map){
console.log("key="+key);
// key=x
// key=y
} // 获取键值
for(let[, value] of map){
console.log("value="+value);
// value=xx
// value=yy
}

4 思考题

为什么func5和func6的结果不一样,请注意为变量赋值和为函数的参数指定默认值

function func5({x=0, y=0}={}){
console.log([x,y]);
}
func5({x:3, y:8}); // [3, 8]
func5({x:3}); // [3, 0]
func5({}); // [0, 0]
func5(); // [0, 0] function func6({ x, y } = { x: 0, y: 0 }){
console.log([x, y]);
}
func6({x:3, y:8}); // [3, 8];
func6({x:3}); // [3, undefined]
func6({}); // [undefined, undefined]
func6(); // [0, 0]

es6基础系列三:解构赋值的更多相关文章

  1. ES6基础-变量的解构赋值

    作者 | Jeskson 来源 | 达达前端小酒馆 解构赋值: 数组的解构赋值,对象的解构赋值,字符串的解构赋值,数值与布尔值的解构赋值,函数参数的解构赋值. 开发环境准备: 编辑器,VS Code, ...

  2. 石川es6课程---6、解构赋值

    石川es6课程---6.解构赋值 一.总结 一句话总结: 结构相同一一对应的方式赋值:let [json, arr, num, str] = [{ a: 1, b: 2 }, [1, 2, 3], 8 ...

  3. es6入门2--对象解构赋值

    解构赋值:ES6允许按照一定规则从数组或对象中提取值,并对变量进行赋值.说直白点,等号两边的结构相同,右边的值会赋给左边的变量. 一.数组的解构赋值: 1.基本用法 let [a, b, c] = [ ...

  4. es6之变量的解构赋值

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

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

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

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

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

  7. ES6入门——变量的解构赋值

    1.数组的解构赋值 以前为变量复制,只能直接指定值.现在ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). 本质上,这种写法属于模式匹配,只要等 ...

  8. ES6中变量的解构赋值

    1.数组的解构赋值 基本用法 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). 输出: 上面代码表示,可以从数组中提取值,按照对应位置,对变 ...

  9. ES6学习笔记之解构赋值

    1.数组的解构赋值 简单用法 { // 旧 let a=1,b=3; //新 let [a,b]=[1,3]; console.log(a,b);// 1 3 } 只要等号两边的模式相同,左边的变量就 ...

随机推荐

  1. c#学习内容

    学习winform+DevExpress 界面制作 wpf UIAutomation 控制别的程序 ok c#通过句柄控制别的程序  ok c# 截图  ok c# 多线程  ok c# 数据库myq ...

  2. maven命令创建项目

    1)创建一个Project mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArti ...

  3. memset和memcopy用法

    void *memset(void *s, int ch, size_t n); 函数解释:将s中前n个字节 (typedef unsigned int size_t)用 ch 替换并返回 s . m ...

  4. 模拟Windows任务管理器CPU使用率的动态折线图-农夫山泉

    Delphi的TCanvas类可以实现各种复杂的图形输出功能,基于近期项目的需求,利用它实现了一个很炫的动态折线图(模拟了资源管理器中CPU使用率的折线图),可以直观地展现出数值的实时变化情况. 这段 ...

  5. 实现两个窗口通信方法-postMessage

    此方案可解决跨域而且跨Iframe,而且http和https之间的交互 首先来看一下基本的语法 otherWindow.postMessage(message, targetOrigin, [tran ...

  6. Arc066_E Addition and Subtraction Hard

    传送门 题目大意 给定一个加减法的表达式,让你任意的添加合法的括号对,使的表达式最大. 题解 考虑到任意左括号一定加在减号右边,那么对于第一个左括号,与该左括号相邻的只含有加号的子序列的贡献一定为负, ...

  7. 树套树Day1线段树套平衡树bzoj3196

    您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作:1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)5.查 ...

  8. 多版本Python共存时pip给指定版本的python安装package的方法

    在Linux安装了多版本Python时(例如python2.7和3.6),pip安装的包不一定是用户想要的位置,此时可以用 -t 选项来指定位置. 例如目标位置是/usr/local/lib/pyth ...

  9. TVYJ1266:费解的开关

    我对状态空间的理解:https://www.cnblogs.com/AKMer/p/9622590.html 题目传送门:http://www.joyoi.cn/problem/tyvj-1266 这 ...

  10. Python-RabbitMQ消息队列实现rpc

    客户端通过发送命令来调用服务端的某些服务,服务端把结果再返回给客户端 这样使得RabbitMQ的消息发送端和接收端都能发送消息 返回结果的时候需要指定另一个队列 服务器端 # -*- coding:u ...