空值合并 ?? 替代 || 的逻辑判断

在 JavaScript 开发中,我们经常需要处理变量可能为 nullundefined 的情况。传统上,开发者会使用逻辑或运算符 || 来提供默认值,但这种方式存在一些缺陷。ES11 (ECMAScript 2020) 引入了空值合并运算符 ??,为这种情况提供了更精确的解决方案。

逻辑或 || 的问题

|| 运算符会检查左侧操作数的"假值"(falsy)状态,包括:

  • false
  • 0
  • "" (空字符串)
  • null
  • undefined
  • NaN
javascript 复制代码
const count = 0;
const result = count || 42;
console.log(result); // 42,但我们可能希望保留0

在这个例子中,0 是一个有效的值,但被 || 视为假值而忽略了。

空值合并运算符 ?? 的优势

?? 运算符只在左侧操作数为 nullundefined 时才会返回右侧操作数:

javascript 复制代码
const count = 0;
const result = count ?? 42;
console.log(result); // 0,保留了有效的0值

使用场景对比

  1. 处理用户输入

    javascript 复制代码
    // 使用 ||
    const userInput = "";
    const username = userInput || "Anonymous"; // "Anonymous"
    
    // 使用 ??
    const username = userInput ?? "Anonymous"; // "" (保留空字符串)
  2. 配置默认值

    javascript 复制代码
    const config = { timeout: 0 };
    
    // 使用 ||
    const timeout = config.timeout || 3000; // 3000
    
    // 使用 ??
    const timeout = config.timeout ?? 3000; // 0
  3. 函数参数默认值

    javascript 复制代码
    function connect(options) {
      const port = options.port ?? 8080;
      // ...
    }

注意事项

  1. 运算符优先级?? 的优先级比 || 低,但比 =? 高。在复杂表达式中可能需要使用括号。

  2. 不能与 ||&& 直接混用

    javascript 复制代码
    // 会抛出语法错误
    const result = a && b ?? c;
    
    // 正确的写法
    const result = (a && b) ?? c;
  3. 浏览器兼容性:虽然现代浏览器都支持 ??,但在旧环境中可能需要使用 Babel 等工具进行转译。

实际应用建议

  1. 当你想区分 null/undefined 和其他假值时,使用 ??
  2. 当你确实想检查所有假值时,使用 ||
  3. 在 TypeScript 中,?? 也能很好地工作,并且与可选链运算符 ?. 配合使用效果更佳

结论

ES11 的空值合并运算符 ?? 为 JavaScript 开发者提供了更精确的工具来处理 nullundefined 的情况,避免了 || 运算符对假值的过度捕获。在需要区分空值和假值的场景中,?? 是更合适的选择,它使代码意图更加清晰,行为更加可预测。