【干货】解构赋值,简洁而强大

155 阅读4分钟

前言

ES6引入了解构赋值,让我们更方便地从数组和对象中提取值,使代码更简洁易读。本文将介绍解构赋值的基本用法,并通过简单的例子帮助初学者理解这一特性。

1. 数组的解构赋值

基本用法

在ES6之前,我们通常使用以下方式进行变量赋值:

let a = 1;
let b = 2;
let c = 3;

而ES6提供了一种更简洁的数组解构赋值方式:

let [a, b, c] = [1, 2, 3];

这意味着可以通过一行代码,按照数组中的顺序,将值赋给相应的变量。

嵌套数组的解构

解构赋值同样适用于嵌套数组:

let [foo, [[bar], baz]] = [1, [[2], 3]];
console.log(foo); // 1
console.log(bar); // 2
console.log(baz); // 3

忽略特定元素

可以使用逗号来忽略不需要的元素:

let [, , third] = ["foo", "bar", "baz"];
console.log(third); // "baz"

剩余元素

使用剩余运算符(...)获取数组中的剩余元素:

let [head, ...tail] = [1, 2, 3, 4];
console.log(head); // 1
console.log(tail); // [2, 3, 4]

默认值

可以为解构赋值设置默认值:

let [x = 1] = [undefined];
console.log(x); // 1

let [y = 1] = [null];
console.log(y); // null

ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效。

2. 对象的解构赋值

解构赋值不仅适用于数组,还可以用于对象:

let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
console.log(foo); // "aaa"
console.log(bar); // "bbb"

对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

嵌套对象的解构

与数组类似,解构也适用于嵌套的对象:

let obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};

let { p, p: [x, { y }] } = obj;
console.log(x); // "Hello"
console.log(y); // "World"
console.log(p); // ["Hello", {y: "World"}]

默认值与别名

对象解构也支持默认值,并且可以为变量设置别名:

let { x = 1, y = x } = {};
console.log(x); // 1
console.log(y); // 1

默认值生效的条件是,对象的属性值严格等于undefined

let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
console.log(baz); // "aaa"

对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。foo是匹配的模式,baz才是变量。真正被赋值的是变量baz,而不是模式foo

3. 字符串的解构赋值

const [a, b, c, d, e] = 'hello';
console.log(a, b, c, d, e); // "h" "e" "l" "l" "o"

let { length: len } = 'hello';
console.log(len); // 5

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

4. 数值、布尔值的解构赋值

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

let { toString: s } = 123;
console.log(s === Number.prototype.toString); // true

let { toString: t } = true;
console.log(t === Boolean.prototype.toString); // true

数值和布尔值的包装对象都有toString属性,因此变量s都能取到值。

let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError

由于undefinednull无法转为对象,所以对它们进行解构赋值,都会报错。

5. 函数参数的解构赋值

function add([x, y]){
  return x + y;
}

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

上面代码中,函数add的参数表面上是一个数组,但在传入参数的那一刻,数组参数就被解构成变量xy。对于函数内部的代码来说,它们能感受到的参数就是xy

解构赋值的应用场景

  1. 交换变量的值
let x = 1;
let y = 2;
[x, y] = [y, x];
  1. 从函数返回多个值
function example() {
  return [1, 2, 3];
}
let [a, b, c] = example();
  1. 函数参数的定义
function f([x, y, z]) { /* ... */ }
f([1, 2, 3]);
  1. 提取JSON数据
let jsonData = { id: 42, status: "OK", data: [867, 5309] };
let { id, status, data: number } = jsonData;
  1. 函数参数的默认值
function ajax(url, { async = true, beforeSend = function() {}, cache = true } = {}) {
  // ... do stuff
}
  1. 遍历Map结构
const map = new Map();
map.set('first', 'hello');
map.set('second', 'world');

for (let [key, value] of map) {
  console.log(key + " is " + value);
}
  1. 输入模块的指定方法
const { SourceMapConsumer, SourceNode } = require("source-map");

最后

总的来说,解构赋值是ES6新增的一项强大灵活的特性,为我们处理数组、对象、甚至字符串等数据结构提供了便捷的语法。希望本文的介绍能够帮助大家更好地理解和运用解构赋值这一特性!

我的Gitee:    CodeSpace (gitee.com)

技术小白记录学习过程,有错误或不解的地方还请评论区留言,如果这篇文章对你有所帮助请 “点赞 收藏+关注” ,感谢支持!!