- 数组的解构赋值
- 对象的解构赋值
- 字符串的解构赋值
- 数值和布尔值的解构赋值
- 函数参数的解构赋值
数组的解构赋值
- // ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)
- {
-     // es5
-     let a = 1;
-     let b = 2;
-     let c = 3;
-     console.log(a, b, c); // 1 2 3
- }
- {
-     // es6
-     let [a, b, c] = [1, 2, 3];
-     console.log(a, b, c); // 1 2 3
- }
- // 可以从数组中提取值,按照对应位置,对变量赋值。
- // 本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值
- {
-     let [a, [[b], c]] = [1, [[2], 3]];
-     console.log(a, b, c); // 1 2 3
- }
- {
-     let [, , c] = [1, 2, 3];
-     console.log(c); // 3
- }
- {
-     let [a, , c] = [1, 2, 3];
-     console.log(a, c); // 1 3
- }
- {
-     let [a, b, ...rest] = [1, 2, 3, 4, 5, 6];
-     console.log(a, b, rest); // 1 2 [3, 4, 5, 6]
- }
- {
-     // 如果解构不成功,变量的值就等于undefined
-     let [a, b, ...c] = ["Di-got"];
-     console.log(a, b, c); // Di-got undefined []
-     // 另一种情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。
-     let [d, e] = [1, 2, 3];
-     console.log(d, e); // 1 2
-     let [f, [g], h] = [1, [2, 3], 4];
-     console.log(f, g, h); // 1 2 4
- }
- {
-     // 默认值
-     let [x = 1, y = x] = []; // x=1; y=1
-     let [x = 1, y = x] = [2]; // x=2; y=2
-     let [x = 1, y = x] = [1, 2]; // x=1; y=2
-     let [x = y, y = 1] = []; // ReferenceError: y is not defined
-     // x用y做默认值时,y还没有声明。
- }
对象的解构赋值
-     // 对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
-     // 对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
-     {
-         let { a, b } = { a: 1, b: 2 };
-         console.log(a, b);    // 1 2
-     }
-     {
-         // 变量没有对应的同名属性,导致取不到值,最后等于undefined(解构失败,变量的值等于undefined。)
-         let { a } = { b: 2 };
-         console.log(a); // undefined
-     }
-     {
-         // 默认值
-         let { x = 3 } = {};
-         console.log(x); // 3
-         let { x, y = 5 } = { x: 1 };
-         console.log(x, y) // 1 5
-         let { x: y = 3 } = {};
-         console.log(y); // 3
-         let { x: y = 3 } = { x: 5 };
-         console.log(y) // 5
-         let { message: msg = 'Something went wrong' } = {};
-         console.log(msg); // "Something went wrong"
-     }
-     {
-         // 已经声明的变量用于解构赋值
-         // 错误写法
-         let x;
-         {x} = {x: 1}; // SyntaxError: syntax error
-         // JavaScript 引擎会将{x}理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题。
-         // 正确的写法 (将整个解构赋值语句,放在一个圆括号里面,就可以正确执行)
-         let x;
-         ({x} = {x: 1});
-         // 由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。
-         let arr = [1, 2, 3];
-         let { 0: first, [arr.length - 1]: last } = arr;
-         console.log(first, last); // 1 3
-     }
-     {
-         let metaData = {
-             title: 'wcd',
-             test: [{
-                 title: 'test',
-                 desc: 'description'
-             }]
-         }
-         let { title: esTitle, test: [{ title: cnTitle }] } = metaData;
-         console.log(esTitle, cnTitle);    // wcd test
-     }
字符串的解构赋值
- // 字符串也可以解构赋值
- // 字符串被转化成了一个类似数组的对象
- {
-     const [a, b, c, d, e] = "hello";
-     console.log(a, b, c, d, e); // h e l l o
- }
- {
-     // 类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。
-     let { length: len } = "hello";
-     console.log(len); // 5
- }
数值和布尔值的解构赋值
- // 解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。
- // 注意:解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。
- {
-     let { toString: s } = 123;
-     console.log(s === Number.prototype.toString); // true
- }
- {
-     let { toString: s } = true;
-     console.log(s === Boolean.prototype.toString); // true
- }
函数参数的解构赋值
- // 函数的参数也可以使用解构赋值
- {
-     [[1, 2], [3, 4]].map(([a, b]) => a + b); // [3, 7]
- }
- // 函数参数的解构也可以使用默认值
- // 函数moveOne的参数是一个对象,通过对这个对象进行解构,得到变量x和y的值。如果解构失败,x和y等于默认值。
- {
-     function moveOne({ x = 0, y = 0 } = {}) {
-         return [x, y];
-     }
-     moveOne({ x: 3, y: 8 }); // [3, 8]
-     moveOne({ x: 3 }); // [3, 0]
-     moveOne({}); // [0, 0]
-     moveOne(); // [0, 0]
- }
- // 函数move的参数指定默认值,而不是为变量x和y指定默认值,所以会得到与前一种写法不同的结果。
- {
-     function moveTwo({ x, y } = { x: 0, y: 0 }) {
-         return [x, y];
-     }
-     moveTwo({ x: 3, y: 8 }); // [3, 8]
-     moveTwo({ x: 3 }); // [3, undefined]
-     moveTwo({}); // [undefined, undefined]
-     moveTwo(); // [0, 0]
- }
- // undefined就会触发函数参数的默认值。
- {
-     [1, undefined, 3].map((x = "yes") => x); // [ 1, 'yes', 3 ]
- }