上一章请见:
3. 解构赋值
a. 数组的解构赋值
let [a1, b1, c1] = [1, 2, 3]; console.log(a1, b1, c1); // 1 2 3 let [a2, , c2] = [1, 2, 3]; console.log(a2, c2); // 1 3 let [a3, b3, c3] = [1, 2]; console.log(a3, b3, c3); // 1 2 undefined let [a4, b4, ...c4] = [1, 2]; // 只有最后一位可以用 ... console.log(a4, b4, c4); // 1 2 [] let [a5, b5, c5, ...d5] = [1, 2]; console.log(a5, b5, c5, d5); // 1 2 undefined [] let [a6, [b6], c6] = [1, [2, 3], 3]; console.log(a6, b6, c6); // 1 2 3
另一个是默认值的概念
let [a1 = 1] = []; console.log(a1); // 1 let [a2 = 1] = [2]; console.log(a2); // 2 let [a3 = 1, b3 = 1, c3 = 1, d3 = 1] = [undefined, null, [], 0]; console.log(a3, b3, c3, d3); // 1 null [] 0 function f() { console.log('aaa'); return 'a'; } // 被赋值时不执行 fn let [a4 = f()] = ['x']; console.log(a4); // x let [b4 = f()] = []; console.log(b4); // aaa a let [a51 = 1, b51 = a51] = []; console.log(a51, b51); // 1 1 let [a52 = 3, b52 = a52] = [1, 2]; console.log(a52, b52); // 1, 2 let [a53 = b53, b53 = 1] = []; console.log(a53, b53); // 报错,因为 b53 还未定义不能赋给 a53
b. 对象的解构赋值
当变量只有键时,选择赋值方相同键对应的值给该键;当变量为键值对时,选择赋值方相同键对应的值给该值。
let { a1, b1 } = { a1: "aaa", b1: "bbb" }; console.log(a1, b1); // aaa bbb let { c1 } = { x: "aaa", y: "bbb" }; console.log(c1); // undefined let { x: a2, y: b2 } = { x: "aaa", y: "bbb" }; console.log(a2, b2); // aaa bbb let c2; ({c2} = {c2: 'aaa'}); // 必须加括号 console.log(c2); // aaa let obj = { p: [ 'Hello', { b3: 'World' } ] }; let { p: [a3, { b3 }] } = obj; console.log(a3, b3); // Hello World let obj2 = {}; let arr = []; ({ x: obj2.xx, y: arr[0]} = { x: 123, y: true }); console.log(obj2, arr); // {xx: 123} [true] let { PI, sin, cos } = Math; console.log(PI, sin, cos); // 3.141592653589793 function sin() { [native code] } function cos() { [native code] } let arr2 = [1, 2, 3]; let {0 : first, [arr2.length - 1] : last} = arr2; console.log(first, last); // 1 3
对象的解构赋值也可以设置默认值,与数组的解构赋值基本类似
c. 其他解构赋值
let [a, b, c, d, e] = 'hello'; console.log(a, b, c); // h e l let {length : len} = 'hello'; console.log(len); // 5 let {toString: s} = true; console.log(s === Boolean.prototype.toString) // true
d. 函数参数关于解构赋值的运用
function add([x, y]){ // 即 let [x, y] = [1, 2] return x + y; } add([1, 2]); // 3 let x = [[1, 2], [3, 4]].map(([a, b]) => a + b); console.log(x); // [3, 7] function xx(...values) { console.log(values); } xx(1, 2, 3); // [1, 2, 3] // 对比下面两段代码,请注意参数的默认值问题 // ------------- function fn1({x = 0, y = 0} = {}) { // 即:先合并 {x=0, y=0} 与 {x: 3, y: 8} 再看是否需要默认值 return [x, y]; } fn1({x: 3, y: 8}); // [3, 8] fn1({x: 3}); // [3, 0] fn1({}); // [0, 0] fn1(); // [0, 0] function fn2({x, y} = { x: 0, y: 0 }) { return [x, y]; } fn2({x: 3, y: 8}); // [3, 8] fn2({x: 3}); // [3, undefined] fn2({}); // [undefined, undefined] fn2(); // [0, 0]
e. 解构赋值的其他应用
// 交换变量的值 let x = 1, y = 2; [x, y] = [y, x]; console.log(x, y); // 2 1 // 无序对应 function f({x, y, z}) { console.log(x, y, z); // 1 2 3 } f({z: 3, y: 2, x: 1}); // 拿到 json 对应的值 let jsonData = { id: 42, status: "OK", data: [867, 5309] }; let { id, status, data: number } = jsonData; console.log(id, status, number); // 42 OK [867, 5309] // 设置参数的默认值 function guid(len=5) { return Math.random().toString(36).substring(2, len+2); } // 与 for-of 愉快地玩耍 let data = [ {Id: 1, Name: 'zyh', Flag: false}, {Id: 2, Name: 'zp'}, ] for (let {Name: name} of data) { console.log(name); // 分别打印 zyh, zp } // 与模块愉快地玩耍 const { fn1, fn2 } = require("utils");
本文部分转载自 阮一峰 的 ECMAScript 6 入门