ES6+ 实战技巧:你真的会用解构和可选链吗?

0 阅读1分钟

引言

ES6(ECMAScript 2015)及其后续版本引入了许多强大的语法特性,其中解构赋值(Destructuring)可选链(Optional Chaining)是两个极其实用但经常被低估的功能。

  • 解构赋值 可以让你从数组或对象中提取数据,并以更简洁的方式赋值给变量。
  • 可选链 则让你安全地访问嵌套对象的属性,避免因 undefinednull 导致的 TypeError

本文将深入探讨它们的高级用法常见误区最佳实践,帮助你写出更简洁、更健壮的 JavaScript 代码。


1. 解构赋值(Destructuring)

1.1 基本用法

数组解构

const numbers = [1, 2, 3];
const [a, b, c] = numbers;

console.log(a); // 1
console.log(b); // 2
console.log(c); // 3

对象解构

const user = { name: "Alice", age: 25 };
const { name, age } = user;

console.log(name); // "Alice"
console.log(age); // 25

1.2 高级技巧

默认值

如果解构的值是 undefined,可以设置默认值:

const { name = "Anonymous", age = 18 } = { name: "Bob" };

console.log(name); // "Bob"
console.log(age); // 18

重命名变量

const { name: userName, age: userAge } = { name: "Charlie", age: 30 };

console.log(userName); // "Charlie"
console.log(userAge); // 30

嵌套解构

const user = {
  id: 1,
  profile: {
    name: "Dave",
    address: {
      city: "New York",
    },
  },
};

const {
  profile: {
    name,
    address: { city },
  },
} = user;

console.log(name); // "Dave"
console.log(city); // "New York"

函数参数解构

function greet({ name, age = 18 }) {
  console.log(`Hello, ${name}! You are ${age} years old.`);
}

greet({ name: "Eve" }); // "Hello, Eve! You are 18 years old."

1.3 常见误区

1. 解构 null 会报错

const { name } = null; // TypeError: Cannot destructure property 'name' of 'null'

解决方案:确保对象存在或提供默认值。

2. 解构数组时跳过某些元素

const [first, , third] = [1, 2, 3];
console.log(first); // 1
console.log(third); // 3

3. 解构剩余元素

const [first, ...rest] = [1, 2, 3, 4];
console.log(rest); // [2, 3, 4]

2. 可选链(Optional Chaining ?.

2.1 基本用法

可选链允许安全访问深层嵌套属性,避免 TypeError

const user = {
  profile: {
    name: "Alice",
  },
};

// 传统写法(容易报错)
const city = user.profile.address.city; // TypeError if `address` is undefined

// 可选链写法(安全访问)
const city = user.profile?.address?.city; // undefined

2.2 高级技巧

1. 函数调用可选链

const user = {
  greet() {
    return "Hello!";
  },
};

console.log(user.greet?.()); // "Hello!"
console.log(user.sayHi?.()); // undefined(不会报错)

2. 数组索引可选链

const users = [{ name: "Bob" }];
console.log(users?.[0]?.name); // "Bob"
console.log(users?.[1]?.name); // undefined

3. 结合空值合并运算符( ??

const city = user.profile?.address?.city ?? "Unknown";
console.log(city); // "Unknown"(如果任何一层是 undefined/null)

2.3 常见误区

1. 滥用可选链

// ❌ 不推荐:过度使用可选链
const name = user?.profile?.name;

// ✅ 推荐:确保数据结构合理,必要时才用可选链
const name = user.profile.name; // 如果确定 `profile` 存在

2. 可选链不能用于赋值

user?.profile?.name = "Alice"; // SyntaxError

3. 可选链 vs && 链式检查

// 传统写法
const city = user && user.profile && user.profile.address && user.profile.address.city;

// 可选链写法(更简洁)
const city = user?.profile?.address?.city;

3. 解构 + 可选链的实战组合

3.1 安全解构深层嵌套对象

const user = {
  profile: {
    name: "Frank",
  },
};

const { profile: { name, age = 25 } = {} } = user;

console.log(name); // "Frank"
console.log(age); // 25 (默认值)

3.2 API 响应处理

const response = {
  data: {
    user: {
      id: 1,
      name: "Grace",
    },
  },
  error: null,
};

// 安全解构 + 可选链
const {
  data: { user: { name } = {},
  error,
} = response;

console.log(name); // "Grace"
console.log(error); // null

3.3 动态配置读取

const config = {
  theme: {
    dark: {
      primary: "#000",
    },
  },
};

const primaryColor = config?.theme?.dark?.primary ?? "#fff";
console.log(primaryColor); // "#000"(如果存在,否则 "#fff")

4. 最佳实践总结

场景推荐写法说明
安全访问属性obj?.prop避免 TypeError
默认值设置const { name = "Anonymous" } = obj;防止 undefined
嵌套解构const { a: { b } } = obj;深层解构
函数参数解构function fn({ name, age }) { ... }更清晰的参数
动态 API 数据处理const name = data?.user?.name ?? "Unknown";安全访问 + 默认值

5. 结论

解构和可选链是 ES6+ 最实用的两个特性,合理使用可以:
减少冗余代码
增强代码健壮性
提升可读性

你平时是如何使用解构和可选链的?欢迎在评论区分享你的经验! 🚀