持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情
字符串
const [a, b, c] = '吴小白';
a; // "吴"
b; // "小"
c; // "白"
字符串还有 length属性,可以对它进行解构赋值
let { length: len } = '吴小白';
len; // 3
数组
用法
左边的变量会按顺序被赋予对应的值
let [a, b, c] = [1, 2, 3];
多层嵌套的数组解构
let [foo, [[bar], baz]] = [1, [[2], 3]];
foo; // 1
bar; // 2
baz; // 3
不完全解构
let [x, , y] = [1, 2, 3];
x; // 1
y; // 3
let [x, y, z] = [1, [2, 2.1], 3];
x; // 1
y; // 2
z; // 3
解构不成功,变量的值就等于undefined。
let [x, y, ...z] = ['a'];
x; // "a"
y; // undefined
z; // []
let [x, ...y] = [1, 2, 3, 4];
x; // "a"
y; // [2, 3, 4]
对于 Set 结构,也可以使用数组的解构赋值。
let [x, y, z] = new Set(['a', 'b', 'c']);
x; // 'a'
y; // 'b'
z; // 'c'
只要某种数据结构具有 Iterator(遍历器) 接口,都可以采用数组形式的解构赋值。
设置默认值
let [foo = true] = [];
foo; // true
let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
let [x = 1] = [undefined];
x; // 1
let [x = 1] = [null];
x; // null
对象
用法
与数组不同的是,对象的属性没有顺序的,因此变量必须与属性同名,才能取到正确的值。
let { foo, bar, baz } = { foo: 'a', bar: 'b' };
foo; // "a"
bar; // "b"
baz; // undefined
上面的代码 baz 没有对应的属性名导致取不到值,因此是 undefined。
万一这个 key 值已经在别的地方使用了,这里会重复怎么办?不要担心,这里可以使用别名。
let { foo: f, bar: b, baz } = { foo: 'a', bar: 'b' };
f; // "a"
b; // "b"
baz; // undefined
这是不是说明了实际应该是这样子的
let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' };
先找到对应的 key ,然后才进行的复制操作,所以真正被赋值的是 f, 而不是 foo, foo只是用来匹配的。
嵌套赋值
let obj1 = {
p: ['Hello', { y: 'World' }],
};
let {
p: [x, { y }],
} = obj1;
x; // "Hello"
y; // "World"
let obj2 = {};
let arr = [];
({ foo: obj2.prop, bar: arr[0] } = { foo: 123, bar: true });
obj2; // {prop:123}
arr; // [true]
如果结构时候子对象所在的父属性里面没有就会报错。所以在对象的解构的时候一定要注意父属性里面是否有对应的 key。
let {
foo: { bar },
} = { baz: '1' };
// Cannot read properties of undefined (reading 'bar')
设置默认值
let { x = 1 } = {};
x; // 1
let { x, y = 22 } = { x: 2 };
x; // 2
y; // 22
let { x: y = 3 } = {};
y; // 3
let { x: y = 3 } = { x: 4 };
y; // 4
函数参数
用法
function add([a, b]) {
return a + b;
}
add([1, 2]); // 3
数组参数就被解构成变量a和b
[
[1, 2],
[3, 4],
].map(([a, b]) => a + b);
// [3, 7]
使用默认值
function log({ x = 0, y = 0 } = {}) {
console.log(x, y);
}
log({ x: 6, y: 8 }); // 6, 8
log({ x: 6 }); // 6, 0
log({}); // 0, 0
log(); // 0, 0
还有一种情况
function log({ x, y } = { x: 0, y: 0 }) {
console.log(x, y);
}
log({ x: 3, y: 8 }); // 3, 8
log({ x: 3 }); // 3, undefined
log({}); // undefined, undefined
log(); // 0, 0
第一种写法,为函数log的参数的变量指定默认值
第二种写法,为函数log的参数指定默认值,而不是为变量x和y指定默认值
数值和布尔值
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。
let { toString: s } = 123;
s === Number.prototype.toString; // true
let { toString: s } = true;
s === Boolean.prototype.toString; // true
数值和布尔值的包装对象都有toString属性,因此变量 s 都能取到值。
如果等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。
let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError