不具备Iterator
只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值。
let [x, y, z] = new Set(['a', 'b', 'c']);
x // "a"
function* fibs() {
let a = 0;
let b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
let [first, second, third, fourth, fifth, sixth] = fibs();
sixth // 5
当一个数组成员严格等于undefined,默认值才会生效。
触发默认值时,才会执行f()
对象的属性没有次序,变量必须与属性同名,才能取到正确的值
let {
bar, foo } = {
foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"
let {
baz } = {
foo: 'aaa', bar: 'bbb' };
baz // undefined
let {
log, sin, cos } = Math;
const {
log } = console;
log('hello') // hello
变量名与属性名不一致
let obj = {
first: 'hello', last: 'world' };
let {
first: f, last: l } = obj;
f // 'hello'
l // 'world'
解构也可以用于嵌套结构的对象。
let obj = {
p: [
'Hello',
{
y: 'World' }
]
};
let {
p: [x, {
y }] } = obj;
x // "Hello"
y // "World"
上面的p只是中间人,如果想用p,怎么办
let obj = {
p: [
'Hello',
{
y: 'World' }
]
};
let {
p, p: [x, {
y }] } = obj;
x // "Hello"
y // "World"
p // ["Hello", {y: "World"}]
对象的解构赋值可以取到继承的属性。
const obj1 = {
};
const obj2 = {
foo: 'bar' };
Object.setPrototypeOf(obj1, obj2);
const {
foo } = obj1;
foo // "bar"
对象默认值
var {
x, y = 5} = {
x: 1};
x // 1
y // 5
var {
x: y = 3} = {
};
y // 3
var {
x: y = 3} = {
x: 5};
y // 5
默认值生效的条件是,对象的属性值严格等于undefined。
var {
x = 3} = {
x: undefined};
x // 3
var {
x = 3} = {
x: null};
x // null
解构修改已知变量值
由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。
let arr = [1, 2, 3];
let {
0 : first, [arr.length - 1] : last} = arr;
first // 1
last // 3
字符串解构
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
let {
length : len} = 'hello';
len // 5
右边是数值和布尔值,则会先转为对象。
let {
toString: s} = 123;
s === Number.prototype.toString // true
let {
toString: s} = true;
s === Boolean.prototype.toString // true
let {
prop: x } = undefined; // 无法转为对象,所以会报错。
let {
prop: y } = null; // 无法转为对象,所以会报错。
函数参数解构