破坏性分配听起来很复杂。 它使我想起了面向对象的术语,例如封装和多态性 。 我相信选择它们是为了使简单的概念显得更加复杂!
本质上,ECMAScript 6(ES2015)的解构分配使您可以从数组或对象中提取单个项目,然后使用速记语法将其放入变量中。 来自PHP的用户可能遇到了list()函数,该函数可以在一个操作中将数组提取为变量。 ES6将其提升到另一个层次。
假设我们有一个数组:
var myArray = ['a', 'b', 'c'];
我们可以通过ES5中的索引提取这些值:
var
one = myArray[0],
two = myArray[1],
three = myArray[2];
// one = 'a', two = 'b', three = 'c'
ES6解构允许使用更简单,更不易出错的替代方法:
const [one, two, three] = myArray;
// one = 'a', two = 'b', three = 'c'
您可以忽略某些值,例如
const [one, , three] = myArray;
// one = 'a', three = 'c'
或使用rest运算符( ...
)提取剩余元素:
const [one, ...two] = myArray;
// one = 'a', two = ['b, 'c']
销毁也适用于对象,例如
var myObject = {
one: 'a',
two: 'b',
three: 'c'
};
// ES5 example
var
one = myObject.one,
two = myObject.two,
three = myObject.three;
// one = 'a', two = 'b', three = 'c'
// ES6 destructuring example
const {one, two, three} = myObject;
// one = 'a', two = 'b', three = 'c'
在此示例中,变量名称one
, two
和three
与对象属性名称匹配。 我们还可以将属性分配给任何名称的变量,例如
const myObject = {
one: 'a',
two: 'b',
three: 'c'
};
// ES6 destructuring example
const {one: first, two: second, three: third} = myObject;
// first = 'a', second = 'b', third = 'c'
也可以引用更复杂的嵌套对象,例如
const meta = {
title: 'Destructuring Assignment',
authors: [
{
firstname: 'Craig',
lastname: 'Buckler'
}
],
publisher: {
name: 'SitePoint',
url: 'http://www.sitepoint.com/'
}
};
const {
title: doc,
authors: [{ firstname: name }],
publisher: { url: web }
} = meta;
/*
doc = 'Destructuring Assignment'
name = 'Craig'
web = 'http://www.sitepoint.com/'
*/
这看起来有些复杂,但请记住在所有解构任务中:
- 分配的左侧是销毁目标 -定义要分配的变量的模式
- 分配的右侧是解构源 -包含要提取的数据的数组或对象。
还有其他一些警告。 首先,您不能以大括号开头的语句,因为它看起来像一个代码块,例如
// THIS FAILS
{ a, b, c } = myObject;
您必须声明变量,例如
// THIS WORKS
const { a, b, c } = myObject;
或如果已经声明了变量,则使用括号,例如
// THIS WORKS
({ a, b, c } = myObject);
您还应该注意混合声明和未声明的变量,例如
// THIS FAILS
let a;
let { a, b, c } = myObject;
// THIS WORKS
let a, b, c;
({ a, b, c } = myObject);
这就是解构的基础。 那么什么时候有用? 我很高兴你问...
轻松申报
可以在不显式定义每个值的情况下声明变量,例如
// ES5
var a = 'one', b = 'two', c = 'three';
// ES6
const [a, b, c] = ['one', 'two', 'three'];
诚然,解构后的版本更长。 读取起来稍微容易一些,尽管更多项目可能并非如此。
可变值交换
在ES5中交换值需要一个临时的第三个变量,但是它的解构要简单得多:
var a = 1, b = 2;
// ES5 swap
var temp = a;
a = b;
b = temp;
// a = 2, b = 1
// ES6 swap back
[a, b] = [b, a];
// a = 1, b = 2
您不仅限于两个变量; 可以重新排列任意数量的项目,例如
// rotate left
[b, c, d, e, a] = [a, b, c, d, e];
默认功能参数
假设我们有一个输出meta
对象的函数:
var meta = {
title: 'Destructuring Assignment',
authors: [
{
firstname: 'Craig',
lastname: 'Buckler'
}
],
publisher: {
name: 'SitePoint',
url: 'http://www.sitepoint.com/'
}
};
prettyPrint(meta);
在ES5中,必须解析此对象以确保可以使用适当的默认值,例如
// ES5 default values
function prettyPrint(param) {
param = param || {};
var
pubTitle = param.title || 'No title',
pubName = (param.publisher && param.publisher.name) || 'No publisher';
return pubTitle + ', ' + pubName;
}
在ES6中,我们可以为任何参数分配默认值,例如
// ES6 default value
function prettyPrint(param = {}) {
但是我们可以使用解构来提取值并在必要时分配默认值:
// ES6 destructured default value
function prettyPrint(
{
title: pubTitle = 'No title',
publisher: { name: pubName = 'No publisher' }
} = {}
) {
return pubTitle + ', ' + pubName;
}
我不认为这更容易阅读,但要短得多。
从函数返回多个值
函数只能返回一个值,但可以是复杂的对象或多维数组。 解构分配使此操作更加实用,例如
function f() {
return [1, 2, 3];
}
const [a, b, c] = f();
// a = 1, b = 2, c = 3
迭代
考虑一系列书籍信息:
const books = [
{
title: 'Full Stack JavaScript',
author: 'Colin Ihrig and Adam Bretz',
url: 'http://www.sitepoint.com/store/full-stack-javascript-development-mean/'
},
{
title: 'JavaScript: Novice to Ninja',
author: 'Darren Jones',
url: 'http://www.sitepoint.com/store/leaern-javascript-novice-to-ninja/'
},
{
title: 'Jump Start CSS',
author: 'Louis Lazaris',
url: 'http://www.sitepoint.com/store/jump-start-css/'
},
];
ES6的for-of与for-in
相似,除了它提取每个值而不是索引/键,例如
for (const b of books) {
console.log(b.title + ' by ' + b.author + ': ' + b.url);
}
销毁分配提供了进一步的增强,例如
for (const {title, author, url} of books) {
console.log(title + ' by ' + author + ': ' + url);
}
正则表达式处理
诸如match之类的正则表达式函数返回匹配项的数组,这些项可以构成解构分配的来源:
const [a, b, c, d] = 'one two three'.match(/\w+/g);
// a = 'one', b = 'two', c = 'three', d = undefined
解构分配支持
销毁工作可能不会改变您的开发生涯,但是可以节省一些打字工作!
目前, 对销毁分配的支持很好。 它可以在Node和所有主要浏览器中使用,Internet Explorer除外。 如果需要支持较旧的浏览器,建议使用Babel或Traceur之类的编译器,它将ES6的解构分配转换为等效的ES5。
From: https://www.sitepoint.com/es6-destructuring-assignment/