基本用法:
1. let a = 1;
2. let b = 2;
3. let c = 3;
1. let [a,b,c] =[1,2,3];
let [foo,[[bar],baz]] = [1,[[2],3]]
foo //1
bar //2
baz //3
let [ , , third] = ["foo","bar","baz"];
third //"baz"
let [x, , y] = [1,2,3];
x //1
y //3
let[head,...tail] = [1,2,3,4]
head //1
tail //[2,3,4]
let [x,y,...z]=['a'];
x //"a"
y //undefined
z // []
undefined
let [foo] = []
let [bar,foo] = [1];
let [x, y] = [1,2,3];
x //1
y //2
let [a,[b],d] = [1,[2,3],4];
a //1
b //2
c //4
//报错
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {
};
let [x,y,z] = new Set(['a','b','c']);
x //"a"
let [foo = true] =[];
foo //true
let [x,y = 'b'] = ['a']; //x='a',y='b'
let [x,y = 'b'] = ['a',undefind]; //x='a', y='b'
注意:
ES6内部使用严格相等运算符(===
), 判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined
,默认才会生效。如果数组成员为null
,默认值就不会生效,因为null
不严格等于undefined
。let [x = 1] = [undefined];
x //1
let[x = 1] = [null];
x //null
function f(){
console.log('aaa')
}
let[x = f()] = [1];
上面的代码中,因为
x能取到值,所以函数
f根本不会执行。上面的代码其实等价于下面的代码。
let x;
if ([1][0] === undefined){
x = f();
} else {
x = [1][0]
}
let [x = 1, y = x] = []; //x=1; y=1
let [x = 1, y = x] = [2]; //x=2; y=2
let [x = 1, y = x] = [1,2]; //x=1;y=2
let [x = y ,y = 1] = []; //ReferenceError: y is not defined
let {
foo , bar } = {
foo: "aaa",bar: "bbb"};
foo //"aaa"
bar //"bbb"
let {
bar , foo } = {
foo: "aaa",bar: "bbb" };
foo //"aaa"
bar //"bbb"
let {
baz} = {
foo: "aaa", bar: "bbb" }
baz //undefined
let {
foo : baz } = {
foo: "aaa" ,bar: "bbb"};
baz //"aaa"
let obj = {
first: "hello" ,last: "world"};
let {
first: f,last: l} = obj;
f //"helllo"
l //'world'
let {
foo: foo , bar: bar } = {
foo: "aaa",bar:"bbb"};
let {
foo: baz } = {
foo:"aaa",bar: "bbb"};
baz //"aaa"
foo //error:foo is not defined
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"}]
let a = {
};
let b = [];
({
foo: a.prop, bar: b[0] } = {
foo: 123, bar: true});
a //{prop:123}
arr //[true]
var {
x = 3 } = {
};
x //3
var {
x, y = 5 } = {
x: 1};
x //1
y //5
var {
x : y = 3} = {
};
y //3
var {
x: y = 3} = {
x: 5};
y //5
var {
message:msg = "Something"} ={
}
msg //"Something"
undefined
。属性x
等于null
,因为null
与undefined
不严格相等,所以是个有效的赋值,导致默认值3
不会生效。如果解构失败,变量的值等于undefined
var {
x = 3 } = {
x : undefined};
x //3
var {
x = 3} = {
x : null}
x //null
let {
foo } = {
bar: "baz"};
foo //undefined
let {
foo} = {
bar: "baz"};
foo // undefined
foo
属性。对应一个子对象,该子对象的bar
属性,解构时会报错,因为foo
这时等于undefined
,再取子属性就会报错。//报错
let {
foo:{
bar}} = {
baz: "baz"};
//报错
let x,
{
x} = {
x: 1};
//SyntaxError: syntax error
//正确
let x,
({
x} = {
x: 1});
({
} = [true,false]);
({
} = "abc");
({
} = []);
let {
log, sin, cos } = Math;
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
length
属性,因此还可以对这个属性解构赋值。let {
length : len} = "hello"
len //5
toString
属性,因此变量s
都能取到值。let {
toString : s} = 123;
s === Number.prototype.toString //true
let {
toString : s} = true;
s === Number.prototype.toString //true
undefined
和null
无法转为对象,所以对他们进行解构赋值,都会报错。let {
prop: x } = undefined; // TypeError
let {
prop: y } = null; //TypeError
add
的参数表面上是一个数组,但在传入参数时,数组参数就被结构成了x
和y
,对于函数内部的代码来说,他们感受到的参数就是x
和y
。function add ([x,y]){
return x + y;
}
add([1,2]); //3
[[1,2], [3,4]].map(([a,b]) =>a + b );
//[3,7]
move
的参数是一个对象,通过对这个对象进行解构,得到变量x
和y
的值,如果解构失败,x
和y
等于默认值。function move ({
x = 0 , y = 0 }= {
}){
return [x,y];
}
move({
x : 3, y : 8}); // [3, 8]
move({
x:3}); // [3, 0]
move({
}); // [0, 0]
move(); // [0, 0]
// 报错
let [(a)] = [1];
let {
x: (c)} = {
};
let ({
x: c}) = {
};
let {
(x: c)} = {
};
let {
(x): c} = {
};
let {
o: ({
p: p }) } = {
o: {
p: 2 } };
// 报错
function f([(z)]) {
return z; }
// 报错
function f([z,(x)]) {
return x; }
// 全部报错
({
p: a }) = {
p: 42 };
([a]) = [5];