ECMAScript 6 解构赋值 Destructuring assignment

 2015年11月07日    443     声明


ECMAScript 6中增加了新的变量赋值方式:解构赋值Destructuring assignment),这种赋值方式会从数组或对象中提取数据,实现在一行中赋值多个变量。

  1. 解构赋值语法格式
  2. 解构赋值相关说明
  3. 数组的解构赋值
  4. 对象的解构赋值


1. 解构赋值语法格式

[a, b] = [1, 2]
[a, b, ...rest] = [1, 2, 3, 4, 5]
{a, b} = {a:1, b:2}
{a, b, ...rest} = {a:1, b:2, c:3, d:4}  //ES7

解构赋值是JavsScript在ECMAScript 6语言标准中新增的表达式结构。这种语法结构模仿了数组字面量和对象字面量语法,可以从数组或对象中提取数据的语法,实现在一行中同时赋值多个变量。

对于以下三个变量的初始化:

var a = 1;
var b = 2;
var c = 3;

使用解构赋值的方式,可以写成下面这样:

var [a, b, c] = [1, 2, 3];


2. 解构赋值相关说明

对象和数组字面量表达式提供了一种简单的定义一个数据包的方法。一旦你创建了这类数据包,你可以用任意的方式使用这些数据包。甚至可以从函数中返回它们。

解构赋值的一个特别有用的功能是:你可以用一个表达式读取整个结构。

解构赋值的作用与PerlPython语言中的特性相似。


3. 数组的解构赋值

解构赋值可以以简单的方式将数组的值分别赋值到多个变量中:

var foo = ["one", "two", "three"];

// 不使用解构赋值
var one   = foo[0];
var two   = foo[1];
var three = foo[2];赋值语句声明。

// 使用解构赋值
var [one, two, three] = foo;

赋值而不声明

解构赋值可以不声明,而是直接在赋值语句中声明。

var a, b;

[a, b] = [1, 2];

交换变量

解构赋值可以非常简单的实现两个变量值的交换,而不必定义中间变量:

var a = 1;
var b = 3;

[a, b] = [b, a];

返回多个值

解构赋值让函数可以一次返回多个值。像下面这样,将两个返回值用括号括起来,它们就能像类似数组的方式被返回:

function f() {
  return [1, 2];
}
var a, b;
[a, b] = f();
console.log("A的值是:" + a + ",B的值是:" + b); //A的值是:1,B的值是:2

解构赋值返回多个值是通过数组的形式实现的,也可以像处理普通数据那样处理其返回值。

忽略部分值

如果解构赋值听某些值是不需要的,可以像下面这样将其忽略:

function f() {
  return [1, 2, 3];
}

var [a, , b] = f();
console.log("A的值是:" + a + ",B的值是:" + b); //A的值是:1,B的值是:3


4. 对象的解构赋值

解构赋值也可以用于对象,对象解构不同于数组,数组的元素的解构由元素序列决定,而对象解构相对更为严格,要求被赋值的变量名与对象属性名相同:

var o = {p: 42, q: true};
var {p, q} = o;

console.log(p); // 42
console.log(q); // true 

// 用新变量名赋值
var {p: foo, q: bar} = o;

console.log(foo); // 42
console.log(bar); // true

赋值而不声明

对象的解构赋值也像数组一样,可以在赋值语句中声明:

var a, b;

({a, b} = {a:1, b:2});

对象和数组嵌套对象的解构

解构赋值可以使用对象和数组嵌套对象:

var metadata = {
    title: "IT笔录",
    description: [
       {
        url: "http://www.itbilu.com",
        title: "itbilu.com"
       }
    ]
};

var { title: name, description: [{ title: domain }] } = metadata;

console.log(name); // "IT笔录"
console.log(domain);  // "itbilu.com"

For of迭代和解构

解构赋值同样在For of循环中适用:

var sites = [
  {
    name: "IT笔录",
    introduce: {
      domain: "itbilu.com",
      title: "IT笔录-学习,记录,整理"
    }
  },
  {
    name: "老聂的小站",
    introduce: {
      domain: "niefengjun.cn",
      title: "聂峰军,聂峰军个人博客"
    }
  },
  {
    name: "一介布衣",
    introduce: {
      domain: "yijiebuyi.com",
      title: "一介布衣,专注 javascript 全栈开发"
    }
  }
];

for (var {name: n, introduce: { title: t, domain: url } } of sites) {
  console.log("name: " + n + ", title: " + t + ", url: " + url);
}
// name: IT笔录, title: IT笔录-学习,记录,整理, url: itbilu.com
// name: 老聂的小站, title: 聂峰军,聂峰军个人博客, url: niefengjun.cn
// name: 一介布衣, title: 一介布衣,专注 javascript 全栈开发, url: yijiebuyi.com

对象属性名计算和迭代和解构赋值

经过计算处理的对象属性名也可以对其使用解构赋值

let key = "z";
let { [key]: foo } = { z: "bar" };

console.log(foo); // "bar"