过一遍ES6(四) --- 其他类型的解构赋值

本文主要内容:
① 字符串的解构赋值
② 数值和布尔值的解构赋值
③ 函数参数的解构赋值
④ 解构赋值过程中圆括号的使用
⑤解构赋值的用途
解构赋值的规则是,只要等号右边的值不是对象或者数组,就先将其转为对象。undefined和null无法转为对象,所以对它们进行解构赋值均会报错
1 字符串的解构赋值
通过解构赋值,字符串被转换为一个类似数组的对象

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

此外,类似数组的对象都有一个length的属性,因此还可以对这个属性解构赋值

let {length : len} = 'hello';
len // 5

2 数值与布尔值的解构赋值
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象

// 代码中,数值和布尔值的包装对象都有toString属性,因此变量s都能取到值
let {toString: s} = 123;
s === Number.prototype.toString // true

let {toString: s} = true;
s === Boolean.prototype.toString // true
// 对undefined和null进行解构赋值将会报错
let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError

3 函数参数的解构赋值

// 虽然给add函数传递的是[]数组形式的参数,此时将会进行解构赋值。
// 即 x = 1 ;y = 2
function add([x, y]){
  return x + y;
}

add([1, 2]); // 3


[[1, 2], [3, 4]].map(([a, b]) => a + b);
// [ 3, 7 ]

函数参数解构赋值设置默认值
①设置默认值

// 参数形式:{x=0,y=0}={},此时相当于x,y均设置默认值为0。
// {}中没有设置x,y的值,所以均为undefined,所以默认值将生效,即x,y均为0
function move({x = 0, y = 0} = {}) {
  return [x, y];
}
// 所以没有传递的参数,将会延用默认值
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]

②通过解构赋值 给{x,y}整体赋值

// 参数形式:{x,y} = {x:0, y:0}
// 此时并不是给x,y设置默认值,而是给{x,y}整体赋值,通过解构赋值得到x,y的值,并不是默认值,所以此时若没有传递某个变量,则该变量将是undefined
function move({x, y} = { x: 0, y: 0 }) {
  return [x, y];
}

move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]

4 圆括号的使用
解构赋值解析并不简单。一个式子在解析到(解析不到)等号的时候才知道是表达式还是模式。所以在尽可能在模式中不放置圆括号
以下三种情况中不允许使用圆括号:
① 声明变量的语句

// 全部报错
let [(a)] = [1];

let {x: (c)} = {};
let ({x: c}) = {};
let {(x: c)} = {};
let {(x): c} = {};

let { o: ({ p: p }) } = { o: { p: 2 } };

② 函数参数中
函数参数也相当于声明变量

// 报错
function f([(z)]) { return z; }
// 报错
function f([z,(x)]) { return x; }

③ 赋值语句的模式

// 全部报错
// 整个模式放在括号中,将报错
({ p: a }) = { p: 42 };
([a]) = [5];

// 报错,部分模式放在括号中
[({ p: a }), { x: c }] = [{}, {}];

只有一种情况下可以使用圆括号:赋值语句的非模式部分

// ①赋值语句并非声明变量语句
// ②圆括号部分是非模式部分

//模式是取数组中的第一个元素
[(b)] = [3]; // 正确
// 模式是p而非d
({ p: (d) } = {}); // 正确
// 模式是取数组中的第一个元素
[(parseInt.prop)] = [3]; // 正确

5 解构赋值的用途
① 变量交换值

let x = 1;
let y = 2;

[x, y] = [y, x];

②函数返回多个参数

// 返回一个数组

function example() {
  return [1, 2, 3];
}
let [a, b, c] = example();

// 返回一个对象

function example() {
  return {
    foo: 1,
    bar: 2
  };
}
let { foo, bar } = example();

③输入模块的指定方法
加载模块时,通常需要指定输入哪些方法,解构赋值将会使输入语句非常清晰

const { SourceMapConsumer, SourceNode } = require("source-map");

④提取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 f([x, y, z]) { ... }
f([1, 2, 3]);

// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});

⑥函数参数设置默认值

jQuery.ajax = function (url, {
  async = true,
  beforeSend = function () {},
  cache = true,
  complete = function () {},
  crossDomain = false,
  global = true,
  // ... more config
} = {}) {
  // ... do stuff
};

⑦遍历map结构,方便获取键值和键名
任何Iterator接口的对象,都可以使用for…of循环遍历。
map结构原生支持iterator接口,配合变量的解构赋值,获取键名和键值非常方便

const map = new Map();
map.set('first', 'hello');
map.set('second', 'world');

for (let [key, value] of map) {
  console.log(key + " is " + value);
}
// first is hello
// second is world

// 获取键名
for (let [key] of map) {
  // ...
}

// 获取键值
for (let [,value] of map) {
  // ...
}

猜你喜欢

转载自blog.csdn.net/hhf235678/article/details/82390022