🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# [Destructuring](https://babeljs.cn/docs/plugins/transform-es2015-destructuring) 在 ES6 中可以使用,支持解构操作。 可以使用 `babel-plugin-transform-es2015-destructuring` 进行语法转换。 ``` npm install --save-dev babel-plugin-transform-es2015-destructuring ``` ## .babelrc 配置 ```json { "plugins": ["transform-es2015-destructuring"] } ``` ## 使用 ### 数组解构 数组解构的格式如下: ``` [ variable1, variable2, ..., variableN ] = array; ``` in ```js let arr = ['aa', 'bb', 'cc'] var [first, second, third] = someArray; console.log(first, second, third) // 'aa', 'bb', 'cc' ``` out ```js var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var arr = ['aa', 'bb', 'cc']; var _someArray = someArray, _someArray2 = _slicedToArray(_someArray, 3), first = _someArray2[0], second = _someArray2[1], third = _someArray2[2]; console.log(first, second, third); ``` #### 多维数组解构 in ```js var [foo, [[bar], baz]] = [1, [[2], 3]]; ``` out ```js var foo = 1, bar = 2, baz = 3; ``` #### 元素留空解构 可以使用留空跳过被解构数组中的某些元素。 in ```js var [,,third] = ["foo", "bar", "baz"]; ``` out ```js var _ref = ["foo", "bar", "baz"], third = _ref[2]; ``` #### 不定参数解构 in ```js var [head, ...tail] = [1, 2, 3, 4]; ``` out ```js var head = 1, tail = [2, 3, 4]; ``` #### 越界解构 当访问空数组或越界访问数组时,对其解构与对其索引的行为一致,最终得到的结果都是:undefined。 in ```js var [missing] = []; console.log(missing); // undefined ``` out ```js var _ref = [], missing = _ref[0]; console.log(missing); // undefined ``` ### 迭代器解构 数组解构赋值的模式同样适用于任意迭代器。 in ```js function* fibs() { var a = 0; var b = 1; while (true) { yield a; [a, b] = [b, a + b]; } } var [first, second, third, fourth, fifth, sixth] = fibs(); console.log(sixth); ``` out ```js var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var _marked = /*#__PURE__*/regeneratorRuntime.mark(fibs); function fibs() { var a, b, _ref; return regeneratorRuntime.wrap(function fibs$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: a = 0; b = 1; case 2: if (!true) { _context.next = 10; break; } _context.next = 5; return a; case 5: _ref = [b, a + b]; a = _ref[0]; b = _ref[1]; _context.next = 2; break; case 10: case "end": return _context.stop(); } } }, _marked, this); } var _fibs = fibs(), _fibs2 = _slicedToArray(_fibs, 6), first = _fibs2[0], second = _fibs2[1], third = _fibs2[2], fourth = _fibs2[3], fifth = _fibs2[4], sixth = _fibs2[5]; console.log(sixth); ``` ### 对象解构 通过解构对象,你可以把它的每个属性与不同的变量绑定,首先指定被绑定的属性,然后紧跟一个要解构的变量。 in ```js var robotA = { name: "Bender", age: 18 }; var robotB = { name: "Flexo", age: 20 }; var { name: nameA, age: ageA } = robotA; var { name: nameB, age: ageB } = robotB; console.log(nameA, ageA); // "Bender", 18 console.log(nameB, ageB); // "Flexo", 20 ``` out ```js var robotA = { name: "Bender", age: 18 }; var robotB = { name: "Flexo", age: 20 }; var nameA = robotA.name, ageA = robotA.age; var nameB = robotB.name, ageB = robotB.age; console.log(nameA, ageA); // "Bender", 18 console.log(nameB, ageB); // "Flexo", 20 ``` #### 对象解构的简写 当属性名与变量名一致时,可以通过一种实用的句法简写: in ```js var { foo, bar } = { foo: "lorem", bar: "ipsum" }; console.log(foo); // "lorem" console.log(bar); // "ipsum" ``` out ```js var _foo$bar = { foo: "lorem", bar: "ipsum" }, foo = _foo$bar.foo, bar = _foo$bar.bar; console.log(foo); // "lorem" console.log(bar); // "ipsum" ``` #### 嵌套解构 in ```js var complicatedObj = { arrayProp: [ "Zapp", { second: "Brannigan" } ] }; var { arrayProp: [first, { second }] } = complicatedObj; console.log(first); // "Zapp" console.log(second); // "Brannigan" ``` out ```js "use strict"; var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var complicatedObj = { arrayProp: ["Zapp", { second: "Brannigan" }] }; var _complicatedObj$array = _slicedToArray(complicatedObj.arrayProp, 2), first = _complicatedObj$array[0], second = _complicatedObj$array[1].second; console.log(first); // "Zapp" console.log(second); // "Brannigan" ``` ### 解构的默认值 in ```js var [missing = true] = []; console.log(missing); // true var { message: msg = "Something went wrong" } = {}; console.log(msg); // "Something went wrong" var { x = 3 } = {}; console.log(x); // 3 ``` out ```js var _ref = [], _ref$ = _ref[0], missing = _ref$ === undefined ? true : _ref$; console.log(missing); // true var _ref2 = {}, _ref2$message = _ref2.message, msg = _ref2$message === undefined ? "Something went wrong" : _ref2$message; console.log(msg); // "Something went wrong" var _ref3 = {}, _ref3$x = _ref3.x, x = _ref3$x === undefined ? 3 : _ref3$x; console.log(x); // 3 ``` ## 注意事项 >[danger] 请注意,当你解构对象并赋值给变量时,如果你已经声明或不打算声明这些变量(亦即赋值语句前没有let、const或var关键字),你应该注意这样一个潜在的语法错误: --- ```js { blowUp } = { blowUp: 10 }; // Syntax error 语法错误 ``` 为什么会出错?这是因为JavaScript语法通知解析引擎将任何以{开始的语句解析为一个块语句(例如,{console}是一个合法块语句)。解决方案是将整个表达式用一对小括号包裹: ```js ({ safe } = {}); // No errors 没有语法错误 ``` >[danger] 当你尝试解构null或undefined时,你会得到一个类型错误: --- ```js var {blowUp} = null; // TypeError: null has no properties(null没有属性) ``` >[warning] 但是,可以解构其它原始类型,例如:布尔值、数值、字符串,但这将得到undefined: --- ```js var {wtf} = NaN; console.log(wtf); // undefined ``` 你可能对此感到意外,但经过进一步审查你就会发现,原因其实非常简单。当使用对象赋值模式时,被解构的值需要被强制转换为对象。大多数类型都可以被转换为对象,但null和undefined却无法进行转换。当使用数组赋值模式时,被解构的值一定要包含一个迭代器。 # 参考资料 [深入浅出ES6(六):解构 Destructuring](http://www.infoq.com/cn/articles/es6-in-depth-destructuring/)