阅读视图

发现新文章,点击刷新页面。

JS判断空值只知道“||”?不如来试试这个操作符

今天我们来聊一个JavaScript里非常实用的语法:空值合并运算符。它的写法是两个问号:??

这个东西有什么用呢?简单说,它帮你处理那些“可能有值,也可能是nullundefined”的情况。

?? 运算符怎么用

空值合并运算符的用法很简单:

let result = 左侧值 ?? 右侧值;

它的规则是:

• 如果左侧值不是null也不是undefined,就返回左侧值

• 如果左侧值nullundefined,就返回右侧值

用这个运算符重写上面的例子:

let user = {
  name: null
};

let displayName = user.name ?? "游客";

console.log(displayName); // 输出:游客

一行代码就搞定了!是不是很简洁?

和 || 运算符的区别

你可能用过||(逻辑或)运算符来设置默认值:

let value = someValue || "默认值";

||??很像,但有一个重要区别:

• || 会在左侧值为 假值 时返回右侧值 • ?? 只在左侧值为 null或undefined 时返回右侧值

JavaScript中的假值包括:

• false

• 0

• ""(空字符串)

• null

• undefined

• NaN

看一个对比例子:

let count0;
let price"";

// 使用 ||
let result1 = count || 10;  // 输出:10(0是假值)
let result2 = price || "未知";  // 输出:"未知"(空字符串是假值)

// 使用 ??
let result3 = count ?? 10;  // 输出:0(0不是null或undefined)
let result4 = price ?? "未知";  // 输出:""(空字符串不是null或undefined)

在实际开发中,如果你希望0false""这些值被保留,就用??。如果你希望所有假值都用默认值替换,就用||

实际场景

场景1:函数参数默认值

function greet(name) {
  // 如果没传name,或者传了null/undefined,就用"朋友"
  let finalName = name ?? "朋友";
  console.log(`你好,${finalName}!`);
}

greet("张三");  // 输出:你好,张三!
greet(null);    // 输出:你好,朋友!
greet();        // 输出:你好,朋友!

场景2:配置对象合并

// 用户设置
let userSettings = {
  themenull// 用户没选主题
  fontSize14
};

// 默认设置
let defaultSettings = {
  theme"light",
  fontSize16,
  language"zh-CN"
};

// 合并设置:优先用用户的,用户没设置就用默认的
let finalSettings = {
  theme: userSettings.theme ?? defaultSettings.theme,
  fontSize: userSettings.fontSize ?? defaultSettings.fontSize,
  language: userSettings.language ?? defaultSettings.language
};

console.log(finalSettings);
// 输出:{ theme: "light", fontSize: 14, language: "zh-CN" }

场景3:链式调用

let user = {
  profile: {
    address: {
      city: "北京"
    }
  }
};

// 安全地获取嵌套属性
let city = user?.profile?.address?.city ?? "未知城市";
console.log(city); // 输出:北京

// 如果中间某个属性不存在
let user2 = {
  profile: null
};

let city2 = user2?.profile?.address?.city ?? "未知城市";
console.log(city2); // 输出:未知城市

这里用到了可选链操作符?.,它和??配合使用非常方便。

注意事项

1. 不能直接和&&||一起用

// 这样写会报错
let x = a && b ?? c;  // SyntaxError

// 需要加括号
let x = (a && b) ?? c;  // 正确
let y = a && (b ?? c);  // 正确

2. 优先级问题

??的优先级比=高,但比大多数运算符低。为了代码清晰,建议在复杂表达式中使用括号。

// 这样写可能不是你想要的
let result = a ?? b && c;

// 加括号更清晰
let result = a ?? (b && c);

3. 在旧版本浏览器中可能不支持

??是ES2020引入的语法。如果你需要支持旧浏览器,可能需要使用Babel等工具进行转换。

什么时候用??

记住这个简单的判断标准:

• 当你只想在变量是nullundefined时才用默认值,用??

• 当你想在所有假值(false0""等)情况下都用默认值,用||

在实际项目中,??通常更适合处理配置、用户输入、API响应等场景,因为这些场景中0false""往往是有效值,不应该被默认值替换。

❌