解构赋值语法是ES6的新特性,我们可以借助解构赋值写出简短优雅的代码,多运用解构赋值可以很大的提高 代码的可读性,提高开发效率。现在很多转译工具(如Babel)会帮助我们处理解构赋值语句,自动兼容低版 本的JS引擎,所以我们需要读一读这些辅助代码,才能知道工具为我们做了什么。
解构赋值大致有如下的几种用法:
- 交换变量
let a = 0
let b = 1
let c = 2
[a, b, c] = [b, c, a]
会被转译为:
"use strict";
var a = 0;
var b = 1;
var c = 2;
var _ref = [b, c, a];
a = _ref[0];
b = _ref[1];
c = _ref[2];
_ref;
- 多返回值
function getResult () { return [] }
let [a, b, c] = getResult()
和变量解构一样,返回值会由一个中间变量存储,下面的_slicedToArray
用于把可迭代对象转化成数组
function getResult() { return []; }
var _getResult = getResult(),
_getResult2 = _slicedToArray(_getResult, 3),
a = _getResult2[0],
b = _getResult2[1],
c = _getResult2[2];
- 参数解构
function putArray ([a, b, c]) {}
function putObject ({ x: a, y: b, z: c }) {}
函数传参实际上是隐式的变量赋值,因此也可以使用解构语法,除了数组以外对象也是可以解构的
function putArray(_ref) {
var _ref2 = _slicedToArray(_ref, 3),
a = _ref2[0],
b = _ref2[1],
c = _ref2[2];
}
function putObject(_ref3) {
var a = _ref3.x,
b = _ref3.y,
c = _ref3.z;
}
再来看看_slicedToArray
是怎么运作的,函数看似很长其实并不复杂,实际上就是利用for-of
语句
遍历迭代器,和之前介绍的有很多重复之处
var _slicedToArray = function () {
function sliceIterator(arr, i) {
var _arr = []; // 结果数组
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = arr[Symbol.iterator](),
_step;
!(_iteratorNormalCompletion = (_step = _iterator.next()).done);
_iteratorNormalCompletion = true) { // for-of遍历
_arr.push(_step.value);
if (i && _arr.length === i) break; // 达到指定长度,若未指定则遍历至结束
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return _arr;
}
return function (arr, i) {
if (Array.isArray(arr)) {
return arr;
} else if (Symbol.iterator in Object(arr)) {
return sliceIterator(arr, i); // 若是可迭代对象则只截取前i个
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
};
}();
- 默认属性值
let obj = {
a: 1
}
let {
a = 0,
b = 0
} = obj
解构的同时还可以指定默认参数,对函数传参也一样适用
"use strict";
var obj = {
a: 1
};
var _obj$a = obj.a,
a = _obj$a === undefined ? 0 : _obj$a,
_obj$b = obj.b,
b = _obj$b === undefined ? 0 : _obj$b;
- 深对象赋值
var obj = {
a: 0,
b: {
c: 1,
d: {
e: 2
}
}
}
var {
a,
b: {
d: {
e: e
}
}
} = obj
解构赋值还可以用于获取深对象中的属性值,不过为了更安全的操作最好还是用_.get()
"use strict";
var obj = {
a: 0,
b: {
c: 1,
d: {
e: 2
}
}
};
var a = obj.a,
e = obj.b.d.e;