解构赋值:从数组或对象中提取值为相同格式对应位置的变量赋值。下面这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。
一、数组的解构赋值
//ES5
{
let a = 10;
let b = 20;
let c = 30;
console.log(a); // 10
console.log(b); // 20
console.log(c); // 30
}
{
//ES6
let [a, b, c] = [10, 20, 30];
console.log(a); // 10
console.log(b); // 20
console.log(c); // 30
}
嵌套数组进行解构,如果解构不成功,变量的值为undefined
let [a, [[b], c]] = [1, [[2], 3]];
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3
let [, , d] = [1, 2, 3];
console.log(d); // 3
let [e, , f] = [4, 5, 6];
console.log(e); // 4
console.log(f); // 6
let [g, ...h] = [1, 2, 3];
console.log(g); // 1
console.log(h); // [2, 3]
let [i, m, ...n] = [1];
console.log(i); // 1
console.log(m); // undefined
console.log(n); // []
不完全匹配: 等号左边的模式,只匹配一部分的等号右边的数组,也可以解构成功。
let [a, b, c] = [1, 2, 3, 4, 5];
console.log(a);
console.log(b);
console.log(c);
解构赋值允许指定默认值。默认值也可以是表达式,如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。默认值可以引用解构赋值的其他变量,但该变量必须已经声明。
let [a = true] = [];
console.log(a); // true
let [b, c = 1] = [2];
console.log(b); // 2
console.log(c); // 1
let [d = 4] = [5];
console.log(d); // 5
let [e, f = 3] = [6, undefined];
console.log(e); // 6
console.log(f); // 3
let [g = 8] = [null];
console.log(g); // null
function h() {
console.log('h'); //不执行
}
let [i = h()] = [111];
console.log(i); // 111
let [x = 1, y = x] = [];
console.log(x); //1
console.log(y); //1
二、对象的解构赋值
对象的解构赋值和数组是不一样的,数组是按顺序解构赋值,对象是按照属性名解构赋值,变量必须和属性同名才能取到正确的值。如果没有对应的属性名,则变量为undefined
let {name, age} = {name: 'Lilei', age: 30};
console.log(name); // Lilei
console.log(age); // 30
let {sex, hobbies} = {sex: '男'};
console.log(sex); // 男
console.log(hobbies); // undefined
如果变量与属性名不同,需要如下写法:其中username是变量。
let {name: username} = {name: 'Lucy', age: 20};
console.log(username); // Lucy
对象解构也可以嵌套赋值
let obj = {
lilei: [
20,
{level: '优'}
]
};
let {lilei} = obj;
let {lilei: [score, {level}]} = obj;
console.log(lilei); // [20, {level: '优'}]
console.log(score); // 20
console.log(level); // 优
let foot = {
noddle: [
20,
{status: 'sale'}
]
}
let {noddle, noddle: [sprice, {status}]} = foot;
console.log(noddle); // [20, {status: 'sale'}]
console.log(sprice); // 20
console.log(status); // sale
let size = {};
let colors = [];
({a: size.prop, b: colors[0]} = {a: 123, b: 456});
console.log(size); // {prop: 123}
console.log(colors); // [456]
对象解构赋初值
let {a = 1} = {};
console.log(a); // 1
let {b, c = 2} = {b: 3};
console.log(b); // 3
console.log(c); // 2
let {d: e = 3} = {};
console.log(e); // 3
let {f = 4} = {f: null};
console.log(f); // null
如果要将一个已经声明的变量用于解构赋值,那么一定不要将{}直接放在左面,因为js会讲{}作为一个代码段而报错,如果需要这样赋值,要用()将等式括起来。
// 错误的写法
let a;
{a} = {a: 1}; // 报错
// 正确的写法
let a;
({a} = {a: 1});
由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。方括号这种写法,属于“属性名表达式”
let arr = [1, 2, 3];
let {0 : first, [arr.length - 1] : last} = arr;
console.log(first); // 1
console.log(last); // 3
三、字符串的解构赋值
const [a, b, c, d, e] = 'HelloWorld';
console.log(a); // H
console.log(b); // e
console.log(c); // l
console.log(d); // l
console.log(e); // o
const {length: len} = 'HelloWorld';
console.log(len); // 10
四、数值和布尔值的解构赋值
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。数值和布尔值的包装对象都有toString
属性,因此变量s
都能取到值。如果不能转为对象,则报语法错误。
let {toString: s} = 123;
console.log(s === Number.prototype.toString); // true
let {toString: o} = true;
console.log(o === Boolean.prototype.toString); // true
let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError
五、函数参数的解构赋值
function fn([a, b]){
console.log(a); // 1
console.log(b); // 2
}
fn([1, 2]);
function fn1([c = 10, d = 20]) {
console.log(c); // 1
console.log(d); // 20
}
fn1([1]);
六、解构赋值的用途
1.交换变量的值
let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a); // 2
console.log(b); // 1
2.从函数返回多个值
从函数return值只能返回一个值,如果要返回多个值,需要把多个值放在数组或者对象中,再返回出来。有了解构赋值,取出这些值将会很容易。
function f() {
let a = 1;
let b = 2;
let c = 3;
let d = 4;
return [a, b, c, d];
}
let [a, b, c, d] = f();
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3
console.log(d); // 4
3.函数参数的定义和设置默认值
function f({x, y, z}) {
console.log(x); // 1
console.log(y); // 2
console.log(z); // 3
}
f({z: 3, y: 2, x: 1});
function f1({x = 0, y = 0, z = 0}) {
console.log(x); // 0
console.log(y); // 2
console.log(z); // 3
}
f1({z: 3, y: 2});
4.提取json数据
let obj = {
name: 'lilei',
age: 20,
sex: '男',
hobbies: ['唱歌', '跳舞']
};
let {name, age, sex, hobbies = []} = obj;
console.log(name); // lilei
console.log(age); // 20
console.log(sex); // 男
console.log(hobbies); // ['唱歌', '跳舞']
5.遍历map结构
const map = new Map();
map.set('score', 100);
map.set('level', '好');
for (let [key, value] of map) {
console.log(key + ':' + value); // score: 100 level: 好
}
6.require和import时可以按需导入
import {getJSON, post, ajax} from "jquery";
post('demo.php', {id: 1}, (res) => {
console.log(res);
});