解构赋值:ES6允许按照一定规则从数组或对象中提取值,并对变量进行赋值。说直白点,等号两边的结构相同,右边的值会赋给左边的变量。
一、数组的解构赋值:
1.基本用法
let [a, b, c] = [1, 2, 3]; console.log(a, b, c); //1,2,3 let [d, ,] = [1, 2, 3]; console.log(d); //1 let [[e], f] = [[1], 2]; console.log(e, f); //1,2 let [g, ...h] = [1, 2, 3]; console.log(g, h); //1,[2,3]
2.不完全解构---右边提供的值要比变量多
let [[i]] = [[1, 2], 3]; console.log(i); //1
3.解构赋值失败为undefined
let [j] = []; console.log(j); //undefined
4.支持解构赋值提供默认值
let [k = 1, l = 2] = [3]; console.log(k, l); //3,2
let [m = 1, n = 2] = [undefined, null]; console.log(m, n); //1,null
默认值支持是一个表达式,比如一个函数,赋值规则还是遵守先看右边是否为undefined。
function func1() { return 2; } let [o = func1()] = [1]; console.log(o); //1
等同于以下代码:
let o; if ([1][0] === undefined) { o = func1(); } else { o = [1][0]; }
默认值支持使用别的变量,但前提是这个变量已经提前声明,否则会报错。
let [p = 1, q = p] = []; console.log(p, q); //1,1
二、对象的解构赋值
1.基本用法
let { a, b } = { b: 1, a: 2 }; console.log(a, b); //2,1
let { a: a, b: b } = { b: 1, a: 2 }; console.log(a, b); //2,1
不信我们做个测试,看下面的代码,a只是用于做匹配,后者才是赋值。
let { a: b } = { a: 2 }; console.log(b); //2
2.变量解构嵌套使用
let {a: [b, { c }]} = { a: [1, { c: 2 }] }; console.log(b, c); //1,2
3.变量解构赋值失败
let {a: { b }} = { c: { b: 1 } }; console.log(b); //报错
4.变量解构赋值存在继承关系
let obj1 = {}; let obj2 = { a: 1 }; Object.setPrototypeOf(obj1, obj2); let {a} = obj1 console.log(a)//1
5.对象解构赋值也存在默认值
let {a=1,b=2} = {a:undefined,b:null}; console.log(a,b)//1,null
6.对象解构与数组解构的混合使用
因为数组本身也属于特殊对象,所以混合使用并不非法。
let arr = [1,2,3] let {0:a,[arr.length-1]:b} = arr; console.log(a,b)//1,3
上述代码等同于以下代码,以数组下标(索引作为key)
let {0:a,[arr.length-1]:b} = [0:1,1:2,2:3];
三、字符串解构赋值
let [a, b, c, d] = "love"; console.log(a,b,c,d)//l,o,v,e
因为是类数组,所以自然拥有length属性,我们也可以读取length属性进行赋值。
let { length: a } = "love"; console.log(a); //4
四、函数参数解构赋值
规则符合参考数组,对象的解构赋值
function add([a, b]) { return a + b; }; add([1,2])//3
所以函数解构赋值肯定是支持使用默认值的
function add([a = 1, b = 2] = []) { console.log(a + b); } add(); //3 add([3,4]);//7
五、使用解构赋值的好处
1.变量交换值--笔试有这样的题目
let a = 1, b = 2; [a, b] = [b, a]; console.log(a,b)//2,1
2.让函数返回多个值
如果让函数返回多个值,我们可以将这些值放在数组或对象里,但是取值就麻烦了,还要遍历,使用解构赋值就方便很多
function func1() { return [1, 2, 3]; } let [a, b, c] = func1(); console.log(a, b, c); //1,2,3
function func2() { return { a: 1, b: 2 }; } let { a, b } = func2(); console.log(a, b); //1,2
3.让函数参数有所对应
默认给函数参数,参数取值都是按顺序取用户传递的值,但是使用了解构赋值,就不需要按照顺序传递了。
function add(a,b){ console.log(a,b) }; add(1,2)//1,2 //不按照顺序 function add2({b,a}){ console.log(a,b) }; add2({a:1,b:2})//1,2
4.提取JSON数据
let jsonData = { 'name': "echo", 'age': 26, 'address': "深圳" }; let { name, age, address } = jsonData; console.log(name, age, address);
5.为函数形参添加默认值
传统写法:
function add(x, y) { var a = a || 1; var b = b || 2 console.log(a + b); } add()//3
解构赋值写法:
function add({ a = 1, b = 2 } = {}) { console.log(a + b); } add(); //3 add({ a: 4, b: 5 }); //9
6.遍历Map解构
解构赋值能为for...of遍历取值提供遍历,这个只是点我还没看到,先记录
const map = new Map(); map.set(1, 2); map.set('a', 'b'); for (let [key, value] of map) { console.log(key + "is" + value);//1isa 2isb };
当然,你可以只取key或者value,像这样:
for (let [key] of map) { } for (let [, value] of map) { }
7.模块引入方法
只是为不同变量赋予不同的引入方法,利用解构赋值可以为多个变量赋值,比较方便。
const { SourceMapConsumer, SourceNode } = require("source-map");