阐述 JavaScript 中的 Optional Chaining (?.) 和 Nullish Coalescing (??) 运算符如何简化代码并提升健壮性。

各位观众老爷们,大家好!今天咱们来聊聊JavaScript里两个能让代码更优雅、更健壮的小可爱:可选链式调用(Optional Chaining)和空值合并运算符(Nullish Coalescing)。这俩货就像代码界的润滑剂,能有效避免“Uncaught TypeError: Cannot read property of undefined/null”这种让人头疼的错误,让你的代码在面对不确定数据时也能稳如泰山。

一、Optional Chaining (?.):再也不怕“点”到空了!

在JavaScript中,我们经常需要访问嵌套对象的属性,比如 user.profile.address.city。但问题来了,如果 userprofile 或者 address 中间任何一个环节是 nullundefined,就会抛出一个错误,程序就直接嗝屁了。以前我们为了避免这种情况,只能用一堆 && 来判断:

let city;
if (user && user.profile && user.profile.address) {
  city = user.profile.address.city;
} else {
  city = undefined; // 或者其他默认值
}

console.log(city); // 输出 undefined,避免了错误

这段代码虽然能避免错误,但是看起来又臭又长,可读性极差。而且,每多一层嵌套,就要多写一个 &&,简直让人崩溃!

Optional Chaining 就是来拯救我们的。它允许你安全地访问嵌套对象的属性,即使中间某个属性不存在,也不会报错,而是直接返回 undefined。 语法很简单,就是在属性访问的点号 . 前面加上一个问号 ?

const city = user?.profile?.address?.city;

console.log(city); // 输出 undefined,如果 user, profile 或 address 为 null/undefined

是不是简洁多了??. 就像一个“空值保险”,只要遇到 nullundefined,就直接短路,返回 undefined,后面的属性访问就直接跳过了。

Optional Chaining 的使用场景:

  • 访问可能不存在的属性: 这是最常见的用途,可以避免 TypeError
  • 调用可能不存在的方法: 也可以用在方法调用上,比如 user?.profile?.getAddress?.()。如果 getAddress 不是一个函数,或者 profilenullundefined,也不会报错,而是返回 undefined
  • 数组访问: 虽然不常见,但也可以用于数组,比如 arr?.[index]

Optional Chaining 的注意事项:

  • ?. 只能用于属性访问和方法调用,不能用于变量名本身。
  • ?. 只能在 nullundefined 时短路,对于其他 falsy 值(比如 0''false),不会起作用。

举个例子:

假设我们有一个用户对象,但用户信息可能不完整:

const user1 = {
  name: "Alice",
  profile: {
    address: {
      city: "New York"
    }
  }
};

const user2 = {
  name: "Bob"
};

console.log(user1?.profile?.address?.city); // 输出 "New York"
console.log(user2?.profile?.address?.city); // 输出 undefined,不会报错

再来一个方法调用的例子:

const obj1 = {
  myMethod: () => {
    console.log("Method called!");
  }
};

const obj2 = {};

obj1.myMethod?.(); // 输出 "Method called!"
obj2.myMethod?.(); // 不会报错,也不会输出任何东西

如果没有 ?.obj2.myMethod() 就会报错,因为 obj2.myMethodundefined

表格总结 Optional Chaining:

运算符 作用 返回值
?. 安全地访问对象的属性或调用方法,如果链中的任何一个值为 nullundefined 如果链中的任何一个值为 nullundefined,则返回 undefined,否则返回属性值或方法调用的结果

二、Nullish Coalescing (??):终于可以区分 null/undefined0/''/false 了!

Nullish Coalescing 运算符 ?? 提供了一种简洁的方式来为变量设置默认值,但它只在变量的值为 nullundefined 时才生效。这与 || 运算符不同,|| 会将任何 falsy 值(0''falsenullundefined)都视为“空”,并使用默认值。

|| 运算符的问题:

const count = 0;
const displayName = count || "Guest";

console.log(displayName); // 输出 "Guest",因为 0 是一个 falsy 值

在这个例子中,我们希望 displayName 默认为 "Guest",但如果 count 是 0,|| 运算符会错误地将其视为“空”,并使用默认值。这显然不是我们想要的。

?? 运算符的优势:

?? 运算符只在变量的值为 nullundefined 时才使用默认值。对于其他 falsy 值,它会保留变量的原始值。

const count = 0;
const displayName = count ?? "Guest";

console.log(displayName); // 输出 0,因为 count 不是 null 或 undefined

现在,displayName 正确地输出了 0,因为 ?? 运算符只关心 nullundefined

?? 运算符的使用场景:

  • 为变量提供默认值,但只在变量为 nullundefined 时生效。
  • 区分 null/undefined 和其他 falsy 值。

举个例子:

const name = null;
const age = 0;
const message = "";

const defaultName = name ?? "Unknown";
const defaultAge = age ?? 25;
const defaultMessage = message ?? "No message";

console.log(defaultName);    // 输出 "Unknown"
console.log(defaultAge);     // 输出 0
console.log(defaultMessage);  // 输出 ""

?? 运算符的注意事项:

  • ?? 运算符不能与 || 运算符直接连用,否则会抛出一个语法错误。你需要用括号来明确优先级。

    // 错误的写法:
    // const value = null ?? "default" || "anotherDefault"; // SyntaxError: Unexpected token '||'
    
    // 正确的写法:
    const value = (null ?? "default") || "anotherDefault"; // 输出 "default"
    const value2 = null ?? ("default" || "anotherDefault"); // 输出 "default"
  • ?? 运算符的优先级低于 &&|| 运算符。

表格总结 Nullish Coalescing:

运算符 作用 返回值
?? 为变量提供默认值,但只在变量的值为 nullundefined 时生效 如果变量的值不是 nullundefined,则返回变量的值,否则返回默认值

三、Optional Chaining 和 Nullish Coalescing 的组合使用:让代码更上一层楼!

这两个运算符可以一起使用,让你的代码更加简洁、健壮。

例子:

假设我们有一个用户对象,但用户信息可能不完整,并且我们希望为用户的城市设置一个默认值:

const user1 = {
  name: "Alice",
  profile: {
    address: {
      city: "New York"
    }
  }
};

const user2 = {
  name: "Bob"
};

const city1 = user1?.profile?.address?.city ?? "Unknown City";
const city2 = user2?.profile?.address?.city ?? "Unknown City";

console.log(city1); // 输出 "New York"
console.log(city2); // 输出 "Unknown City"

在这个例子中,我们首先使用 Optional Chaining 安全地访问用户的城市信息,如果任何一个环节是 nullundefined?. 运算符会返回 undefined。然后,我们使用 Nullish Coalescing 运算符 ?? 为城市设置一个默认值 "Unknown City"。

四、实际应用场景:

  1. 处理 API 返回的数据:

    API 返回的数据结构可能不固定,某些字段可能不存在。使用 Optional Chaining 和 Nullish Coalescing 可以安全地访问数据,并为缺失的字段提供默认值。

    async function fetchData() {
      const response = await fetch('https://api.example.com/data');
      const data = await response.json();
    
      const userName = data?.user?.name ?? "Guest";
      const userCity = data?.user?.profile?.address?.city ?? "Unknown";
    
      console.log(`User: ${userName}, City: ${userCity}`);
    }
  2. 处理用户配置:

    用户可以自定义配置,但某些配置项可能没有设置。使用 Optional Chaining 和 Nullish Coalescing 可以安全地访问配置项,并为缺失的配置项提供默认值。

    const userConfig = {
      theme: "dark"
      // 没有设置 font size
    };
    
    const theme = userConfig.theme ?? "light";
    const fontSize = userConfig.fontSize ?? 16;
    
    console.log(`Theme: ${theme}, Font Size: ${fontSize}`); // 输出 Theme: dark, Font Size: 16
  3. 处理表单数据:

    表单中的某些字段可能为空。使用 Optional Chaining 和 Nullish Coalescing 可以安全地访问表单数据,并为缺失的字段提供默认值。

    <input type="text" id="name" name="name">
    <input type="number" id="age" name="age">
    const form = document.querySelector('form');
    
    form.addEventListener('submit', (event) => {
      event.preventDefault();
    
      const name = form.elements.name.value || "Anonymous"; // 旧方法,使用 ||
      const age = form.elements.age.value ?? 0; // 使用 ??
    
      console.log(`Name: ${name}, Age: ${age}`);
    });

五、总结:

Optional Chaining (?.) 和 Nullish Coalescing (??) 是 JavaScript 中非常有用的两个运算符,它们可以帮助你编写更简洁、更健壮的代码。

  • ?. 运算符可以安全地访问嵌套对象的属性,避免 TypeError
  • ?? 运算符可以为变量提供默认值,但只在变量的值为 nullundefined 时生效。

合理地使用这两个运算符,可以大大提高代码的可读性和可维护性,减少 bug 的数量,让你在开发过程中更加得心应手。

记住,代码就像盖房子,地基要打牢,细节要做好。Optional Chaining 和 Nullish Coalescing 就是帮你打牢地基,处理好细节的利器。掌握了它们,你的代码就能经得起各种风吹雨打,稳如磐石!

今天的分享就到这里,希望大家有所收获。如果有什么问题,欢迎随时提问! 谢谢大家!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注