解构赋值


SpiderMonkey 1.7 实现了一种混合式赋值,我们称之为「解构赋值」,当发生解构赋值时,右侧的数组和对象中一个或多个值会被提取出来(解构),并赋值给左侧相应的变量名:

let [x, y] = [1, 2]; // x = 1, y = 2
[x, y] = [x + 1, y + 1]; // x = 2, y = 3
[x, y] = [y, x];   // x = 3, y = 2 交换 x 和 y 的值

当和数组配合使用时解构赋值是一种写法简单但又极其强大的功能,特别是在函数返回值是一组结果的时候:

解构赋值右侧的数组所包含的元素不必和左侧的变量一一对应,左侧多余的变量的赋值为 undefined,而右侧多余的值将被忽略,此外左侧变量列表还可以通过包含连续逗号来跳过右侧对应值:

let [x, y] = [1];    // x = 1, y = undefined
[x, y] = [1, 2, 3];  // x = 1, y = 2
[,x,,y] = [1,2,4,5]; // x = 2, y = 5

另外,还有一点需要注意的是整个解构赋值运算的结果是右侧的整个数据结构而不是提取出来的值:

let all, first, second;
all = [first, second] = [1, 2, 3];  // all = [1, 2, 3], first = 1, second = 2

此外,解构赋值支持嵌套数组:

let [one, [two, three]] = [1, [2, 3], 4]; // one = 1, two = 2, three = 3

解构赋值的右侧也可以是一个对象,这种情况下,解构赋值的左侧部分看起来也应当是一个对象直接量,通过左侧的属性名去右侧对象查找对应的属性值:

let transparent = {r:0.0, g:0.0, b:0.0, a:1.0};
let {r:red, g:green, b:blue} = transparent;  // red=0.0, green=0.0, blue = 0.0

对象方法也是属性,所以我们还可以把对象方法通过解构赋值给变量:

// 等价于 sin = Math.sin, cos = Math.cos, tan = Math.tan
let {sin:sin, cos:cos, tan:tan} = Math;

与数组一样,解构赋值也支持嵌套对象,实际上,数组和对象还可以合在一起使用,用来描述任意数据结构:

let data = {
  name: "destructure assignment",
  type: "extension",
  impl: [
    {engine: "spidermonkey", version: 1.7},
    {engine: "rhino", version: 1.7}
  ]
};

// 使用解构赋值从数据结构中提取4个值
let {name: feature, impl: [{engine: impl1, version: v1}, {engine: impl2}]} = data;

console.log(feature);  // destructure assignment
console.log(impl1);    // spidermonkey
console.log(v1);       // 1.7
console.log(impl2);    // rhino

但我们平时很少这么写,因为这种嵌套的解构赋值会让代码的可读性变差。


Vote Vote Cancel Collect Collect Cancel

<< 上一篇: 常量和局部变量

>> 下一篇: 迭代器和生成器