当我们使用 Ajax 向服务器端获取数据时,服务器一般会返回一个对象,这个时候我们需要从对象中提取出需要的数据

const print = console.log;

const data = {
type: 'male',
name: 'Alice'
}

// 从对象中提取出数据
let type = data.type;
let name = data.name;

print(type); // male
print(name); // Alice

下面的内容讲的是 ES6 提供新的语法来方便的做到这件事情。

对象解构

下面的代码可以做到和上面一样的事情

const print = console.log;

const data = {
type: 'male',
name: 'Alice'
}

let {type, name}= data;

print(type); // male
print(name); // Alice

上面使用了 let {name, type} = data 来进行赋值,这行代码的意思就是从 data 对象中提取出 name 和 type 属性,并且赋值到名为 name 和 type 的本地变量中。

默认值

考虑下面的例子

let {type, name, value} = data;

print(type); // male
print(name); // Alice
print(value); // undefined

上面增加了一个 value 变量,我们想从 data 里面提取出 value 属性给变量 value,但是 data 对象并没有 value 属性,所以 value 变量的值是 undefined,现在我们希望如果 data 里面没有 value 属性的话,给变量 value 一个默认值,那么可以这么写

let {type, name, value = 0} = data;

print(type); // male
print(name); // Alice
print(value); // 0

当 data 对象没有 value 属性,或者 value 属性的值为 undefined 时,value 变量就会使用默认值 0。

赋值给非同名变量

let {type, name}= data;

出于某种原因,我们希望将 data.type 属性的值赋值给 localType 的变量而不是 type 变量,那么我们可以这么写

let {type: localType, name} = data;

print(localType); // male
print(type); // ReferenceError: type is not defined

上面代码作用就是提取 data 对象的 type 属性给变量 localType,接着我们分别打印了 localType 和 type 变量的值,发现本地根本没有 type 变量。

嵌套对象解构

考虑一个复杂结构的对象

const data = {
first: {
name: "Alice",
age: 18
},
second: {
name: "Bob",
age: 3
}
}

我们希望将 data.first.name 赋值为一个本地变量 name,那么可以这样写

let {first: {name}} = data;

print(name); // Alice

如果希望将 data.first.name 赋值为别的变量,如 firstName,那么可以这么写

let {first: {name: firstName}} = data;

print(firstName) // Alice
print(name); // ReferenceError: name is not defined

数组解构

数组解构的语法同对象解构的语法相似,不过对象解构是根据名称进行解构,而数组则是根据下标解构

const data = ["red", "green", "blue"];
let [first, second] = data;

print(first); // red
print(second); // green

[first, second] = data 指的就是将 data 数组的第一个元素的值赋值给变量 first,第二个元素的值赋值给变量 second。如果希望只获得第二个元素的值,可以这么写

let [, second] = data;

print(second); // green

默认值

const data = ["red"];
let [first, second] = data;

print(first); // red
print(second); // undefine

因为数组中只有一个元素,所以 second 变量的值为 undefined,我们希望如果数组个数不足时,能为 second 赋值一个默认值,可以采取下面的办法

const data = ["red"];
let [first, second = "white"] = data;

print(first); // red
print(second); // white

当数组值的个数不足时,或者数组元素的值为 undefined 时,就使用默认值。

嵌套数组解构

假设有如下嵌套数组

const data = ["red", ["white", "black"], "yellow"];

现在希望从里面解构出 white,可以这么写

let [, [white]] = data;

print(white); // white

其中第一个 , 表示我们不需要第一个元素,而第二个 [white] 表示我们要第二个元素里面的第一个元素,并将其赋值给 white 变量。

剩余项

使用 ... 语法可以获得数组中的剩余项,例如

let data = ["red", "green", "blue"];
let [first, ...rest] = data;

print(first); // red
print(rest); // [ 'green', 'blue' ]

上面的 [first, ...rest] = data 表示将第一个元素赋值给 first 变量,而剩下的元素赋值给 rest 变量。使用 ... 的语法可以方便的做到数组的复制,如

const data = ["red", "green", "blue"];
let [...copyData] = data;

print(copyData); // [ 'red', 'green', 'blue' ]

解构参数

下面是一个向服务端发送请求的函数

function getData(type, url, options) {
options = options || {};
let timeout = options.timeout,
success = options.success;
error = options.error;
// dosomething
}

除了接收 type,url 两个必须的参数,还可以接收一些配置项由 options 参数给出,在函数中我们将 options 的属性提取出来给了特定的变量,其实上面的操作可以由下写法做到

function getData(type, url, {timeout, success, error} = {}) {
print(timeout); // 5000
print(success); // [Function: success]
print(error); // [Function: error]
// dosomething
}

getData("get", "http://localhost:4000", {
timeout: 5000,
success: function(data) {},
error: function(error) {}
})

我们传入的对象会被解构具体的参数。如果我们希望在没有给出配置项时,参数有默认值,例如 timeout 如果没有被给出的话,我们希望它的值是 3000,根据解构的默认值语法,不难写出如下

function getData(type, url, {timeout = 2000, success, error} = {}) {
print(timeout); // 2000
print(success); // [Function: success]
print(error); // [Function: error]
// dosomething
}

// 没有传入 timeout 参数
getData("get", "http://localhost:4000", {
success: function(data) {},
error: function(error) {}
})