ES6 变量的解构赋值
变量的解构赋值
解构赋值是对赋值运算符的扩展。即结构化赋值
ES6允许我们通过数组或者对象的方式,对一组变量进行赋值,这就称为解构(等号两边的结构一定要相等这样才能拿到你需要的值)
数组中的解构赋值
语法:let [a,b,c] = [1,2,3]
(把右边的值对应下表赋值给左边的变量)
本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值
let [a, b, c] = [1, 2, 3];
// a = 1
// b = 2
// c = 3
可嵌套
let [a, [[b], c]] = [1, [[2], 3]];
// a = 1
// b = 2
// c = 3
可忽略
let [a, , b] = [1, 2, 3];
// a = 1
// b = 3
解析问题
- 如果变量对应没有值来解析,那么变量为undefined
let [a] = [];
// a = undefined
let [b, c] = [1];
// b = 1, c = undefined
let [d, [e], f] = [1, [2, 3], 4];
// d = 1, e = 2, f = 4
- 等号两边的类型不同,解析时会报错
// 报错
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
解构默认值
解构赋值:当变量存在默认值,如果该变量对应的值为undefined,那么变量就被赋予默认值,否则就为对应值
let [a = true] = [];
// a = true
let [x, y = 'b'] = ['a'];
// x='a', y='b'
let [x, y = 'b'] = ['a', undefined];
// x='a', y='b'
对象的解构赋值
语法:let { a, b } = { a: 'aaa', b: 'bbb' }
;(以变量与key对应赋值)
let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
// foo = 'aaa'
// bar = 'bbb'
let { baz : foo } = { baz : 'ddd' };
// foo = 'ddd'
解析问题
- 如果变量对应没有值来解析,那么变量为undefined
let { c } = { a: 'aaa', b: 'bbb' };
// c = undefined
- 对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者
let { a: c } = { a: 'aaa', b: 'bbb' };
// c = "aaa"
// a = error: a is not defined
- 如果要将一个已经声明的变量用于解构赋值
// 错误的写法
let x;
{x} = {x: 1};
// SyntaxError: syntax error
// 正确的写法
let x;
({x} = {x: 1});
默认值
var {x = 1} = {};
// x = 1
var {x = 1} = {x: undefined};
// x = 1
var {x = 1} = {x: null};
// x = null
圆括号问题
尽量不要写带有()的语句出来
解构赋值虽然很方便,但是解析起来并不容易。对于编译器来说,一个式子到底是模式,还是表达式,没有办法从一开始就知道,必须解析到(或解析不到)等号才能知道,乱加圆括号也是导致编译报错
不能使用圆括号的情况:
- 变量声明语句
let [(a)] = [1]
- 函数参数
function fn([(z)]){}
- 赋值语句的模式
[({ p: a }), { x: c }] = [{}, {}];
可以使用圆括号的情况:
[(b)] = [1];
({ p: (d) } = {});
[(parseInt.prop)] = [1];
用途
- 对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量,如此我们可以直接使用这个变量调用现有对象的方法和变量
let { document: test } = window;
// 上面的代码声明了一个变量引用的 window 对象中的 document 属性的值
- 交换变量的值
let a = 1;
let b = 2;
// 下面代码交换变量a和b的值
[a, b] = [b, a];
- 从函数返回多个值
// 返回一个数组
function fun() {
return [1, 2, 3];
}
let [a, b, c] = fun();
// 返回一个对象
function fun() {
return {
foo: 1,
bar: 2
};
}
let { foo, bar } = fun();
// 用解构赋值的 模式伪对象 接收 函数返回的对象或者数组,如此就可以一下子声明好几个变量
- 函数参数的定义
// 参数是一组有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]);
// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});
- 提取 JSON 数据
let Data = {
id: 42,
status: "OK",
data: [666, 999]
};
let { id, status, data: number } = Data ;
console.log(id, status, number);
// 42, "OK", [666, 999]
// 上面代码可以快速提取 JSON 数据的值。
- 函数参数的默认值
- 其实就是来方便我们编写代码的