• 数组的解构赋值
  • 对象的解构赋值
  • 字符串的解构赋值
  • 数值和布尔值的解构赋值
  • 函数参数的解构赋值

数组的解构赋值

  1. // ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)
  2. {
  3. // es5
  4. let a = 1;
  5. let b = 2;
  6. let c = 3;
  7. console.log(a, b, c); // 1 2 3
  8. }
  9. {
  10. // es6
  11. let [a, b, c] = [1, 2, 3];
  12. console.log(a, b, c); // 1 2 3
  13. }
  14. // 可以从数组中提取值,按照对应位置,对变量赋值。
  15. // 本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值
  16. {
  17. let [a, [[b], c]] = [1, [[2], 3]];
  18. console.log(a, b, c); // 1 2 3
  19. }
  20. {
  21. let [, , c] = [1, 2, 3];
  22. console.log(c); // 3
  23. }
  24. {
  25. let [a, , c] = [1, 2, 3];
  26. console.log(a, c); // 1 3
  27. }
  28. {
  29. let [a, b, ...rest] = [1, 2, 3, 4, 5, 6];
  30. console.log(a, b, rest); // 1 2 [3, 4, 5, 6]
  31. }
  32. {
  33. // 如果解构不成功,变量的值就等于undefined
  34. let [a, b, ...c] = ["Di-got"];
  35. console.log(a, b, c); // Di-got undefined []
  36. // 另一种情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。
  37. let [d, e] = [1, 2, 3];
  38. console.log(d, e); // 1 2
  39. let [f, [g], h] = [1, [2, 3], 4];
  40. console.log(f, g, h); // 1 2 4
  41. }
  42. {
  43. // 默认值
  44. let [x = 1, y = x] = []; // x=1; y=1
  45. let [x = 1, y = x] = [2]; // x=2; y=2
  46. let [x = 1, y = x] = [1, 2]; // x=1; y=2
  47. let [x = y, y = 1] = []; // ReferenceError: y is not defined
  48. // x用y做默认值时,y还没有声明。
  49. }

对象的解构赋值

  1. // 对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
  2. // 对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
  3. {
  4. let { a, b } = { a: 1, b: 2 };
  5. console.log(a, b); // 1 2
  6. }
  7. {
  8. // 变量没有对应的同名属性,导致取不到值,最后等于undefined(解构失败,变量的值等于undefined。)
  9. let { a } = { b: 2 };
  10. console.log(a); // undefined
  11. }
  12. {
  13. // 默认值
  14. let { x = 3 } = {};
  15. console.log(x); // 3
  16. let { x, y = 5 } = { x: 1 };
  17. console.log(x, y) // 1 5
  18. let { x: y = 3 } = {};
  19. console.log(y); // 3
  20. let { x: y = 3 } = { x: 5 };
  21. console.log(y) // 5
  22. let { message: msg = 'Something went wrong' } = {};
  23. console.log(msg); // "Something went wrong"
  24. }
  25. {
  26. // 已经声明的变量用于解构赋值
  27. // 错误写法
  28. let x;
  29. {x} = {x: 1}; // SyntaxError: syntax error
  30. // JavaScript 引擎会将{x}理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题。
  31. // 正确的写法 (将整个解构赋值语句,放在一个圆括号里面,就可以正确执行)
  32. let x;
  33. ({x} = {x: 1});
  34. // 由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。
  35. let arr = [1, 2, 3];
  36. let { 0: first, [arr.length - 1]: last } = arr;
  37. console.log(first, last); // 1 3
  38. }
  39. {
  40. let metaData = {
  41. title: 'wcd',
  42. test: [{
  43. title: 'test',
  44. desc: 'description'
  45. }]
  46. }
  47. let { title: esTitle, test: [{ title: cnTitle }] } = metaData;
  48. console.log(esTitle, cnTitle); // wcd test
  49. }

字符串的解构赋值

  1. // 字符串也可以解构赋值
  2. // 字符串被转化成了一个类似数组的对象
  3. {
  4. const [a, b, c, d, e] = "hello";
  5. console.log(a, b, c, d, e); // h e l l o
  6. }
  7. {
  8. // 类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。
  9. let { length: len } = "hello";
  10. console.log(len); // 5
  11. }

数值和布尔值的解构赋值

  1. // 解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。
  2. // 注意:解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。
  3. {
  4. let { toString: s } = 123;
  5. console.log(s === Number.prototype.toString); // true
  6. }
  7. {
  8. let { toString: s } = true;
  9. console.log(s === Boolean.prototype.toString); // true
  10. }

函数参数的解构赋值

  1. // 函数的参数也可以使用解构赋值
  2. {
  3. [[1, 2], [3, 4]].map(([a, b]) => a + b); // [3, 7]
  4. }
  5. // 函数参数的解构也可以使用默认值
  6. // 函数moveOne的参数是一个对象,通过对这个对象进行解构,得到变量x和y的值。如果解构失败,x和y等于默认值。
  7. {
  8. function moveOne({ x = 0, y = 0 } = {}) {
  9. return [x, y];
  10. }
  11. moveOne({ x: 3, y: 8 }); // [3, 8]
  12. moveOne({ x: 3 }); // [3, 0]
  13. moveOne({}); // [0, 0]
  14. moveOne(); // [0, 0]
  15. }
  16. // 函数move的参数指定默认值,而不是为变量x和y指定默认值,所以会得到与前一种写法不同的结果。
  17. {
  18. function moveTwo({ x, y } = { x: 0, y: 0 }) {
  19. return [x, y];
  20. }
  21. moveTwo({ x: 3, y: 8 }); // [3, 8]
  22. moveTwo({ x: 3 }); // [3, undefined]
  23. moveTwo({}); // [undefined, undefined]
  24. moveTwo(); // [0, 0]
  25. }
  26. // undefined就会触发函数参数的默认值。
  27. {
  28. [1, undefined, 3].map((x = "yes") => x); // [ 1, 'yes', 3 ]
  29. }