数组的解构赋值
ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
var a = 1;
var b = 2;
var c = 3;
ES6允许写成下面这样。
var [a, b, c] = [1, 2, 3];
这种写法有点像‘模式匹配’,如果匹配不成功就会返回'undefined'。
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []
如果左边只匹配右边部分值,仍是解构成功。 只要某种数据结构具有Iterator
接口,都可以采用数组形式的解构赋值。
数组可以使用默认值,只要数组成员不严格等于undefined
。
对象的解构赋值
解构不仅可以用于数组,还可以用于对象。 对象的解构赋值与数组的不同,对象的解构赋值变量必须与属性同名。
var { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
这实际上说明,对象的解构赋值是下面形式的简写:
var { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };
对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
var { foo: baz } = { foo: "aaa", bar: "bbb" };
baz // "aaa"
foo // error: foo is not defined
foo
是匹配的模式,baz
才是变量。真正被赋值的是变量baz
,而不是模式foo
。
对象的默认值生效的条件是,对象的属性值严格等于undefined
。
嵌套的对象解构
let node = {
type: "Identifier",
name: "foo",
loc: {
start: {
line: 1,
column: 1
},
end: {
line: 1,
column: 4
}
}
};
let { loc: { start }} = node;
console.log(start.line); // 1
console.log(start.column); // 1
解构模式使用了花括号,表示应当下探到 node
对象的 loc
属性内部去寻找 start
属性。
每当有一个冒号在解构模式中出现,就意味着冒号之前的标识符代表需要检查的位置,而冒号右侧则是赋值的目标。 当冒号右侧存在花括号时,表示目标被嵌套在对象的更深层次中。
字符串的解构赋值
字符串被转换成了一个类似数组的对象。
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
let {length : len} = 'hello';
len // 5
类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。
数值和布尔值的解构赋值
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。 undefined
和null
无法转为对象,所以对它们进行解构赋值,都会报错。
let {toString: s} = 123;
s === Number.prototype.toString // true
let {toString: s} = true;
s === Boolean.prototype.toString // true
let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError
函数参数的解构赋值
函数的参数也可以使用解构赋值,传入参数的时候就会被解构。
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
参考阮一峰的ES6教程