JavaScript 中!!、?? 和 || 使用介绍

在 JavaScript 中,!!、?? 和 || 是三种常用于处理值的真假性或默认值 的操作符,但它们的行为和用途完全不同。下面逐一解释,并对比区别。


1. !! ------ 强制转为布尔值(Boolean)

作用:

将任意值显式转换为布尔类型 (true 或 false)。

原理:

  • 第一个 !:将值转为布尔并取反;
  • 第二个 !:再取反一次,得到原始值的布尔等价值。

示例:

复制代码

js

编辑

复制代码
console.log(!!"hello");   // true
console.log(!!"");        // false
console.log(!!0);         // false
console.log(!!42);        // true
console.log(!!null);      // false
console.log(!!undefined); // false
console.log(!!{});        // true(对象总是 truthy)

常见用途:

  • 显式获取某个值的"是否存在"状态:

    复制代码

    js

    编辑

    复制代码
    const hasEmail = !!user.email; // 确保返回 true/false

2. || ------ 逻辑 OR(短路求值)

作用:

返回第一个 truthy 值;如果所有值都是 falsy,则返回最后一个。

✅ 注意 :它判断的是 falsy / truthy (不是 null/undefined 专属)。

Falsy 值包括:

复制代码

js

编辑

复制代码
false, 0, -0, 0n, "", null, undefined, NaN

示例:

复制代码

js

编辑

复制代码
console.log("a" || "b");        // "a"("a" 是 truthy)
console.log("" || "default");   // "default"
console.log(0 || "number");     // "number"
console.log(null || "ok");      // "ok"
console.log(undefined || "hi"); // "hi"

// 常用于设置默认值(⚠️ 有陷阱!)
function greet(name) {
  name = name || "Guest"; // 如果 name 是 falsy(如 ""、0),也会被替换!
  console.log("Hello, " + name);
}
greet(""); // 输出: Hello, Guest ❌(可能不是你想要的)

⚠️ 问题 :|| 会把 0、""、false 等合法值误判为"无效"。


3. ?? ------ 空值合并操作符(Nullish Coalescing)

作用:

仅当左侧值为 null 或 undefined 时,才返回右侧默认值。

✅ 只对 null / undefined 敏感 ,其他 falsy 值(如 0, "", false)会被保留。

示例:

复制代码

js

编辑

复制代码
console.log("a" ?? "b");        // "a"
console.log("" ?? "default");   // ""(空字符串被保留!)
console.log(0 ?? "number");     // 0(数字 0 被保留!)
console.log(false ?? "bool");   // false
console.log(null ?? "ok");      // "ok"
console.log(undefined ?? "hi"); // "hi"

正确设置默认值:

复制代码

js

编辑

复制代码
function greet(name) {
  name = name ?? "Guest"; // 只有 name 为 null/undefined 时才用默认值
  console.log("Hello, " + name);
}
greet(""); // 输出: Hello,  ✅(空字符串被接受)
greet(null); // 输出: Hello, Guest

🔁 对比总结

表达式 判断条件 返回值示例
`a b`
a ?? b 如果 a 是 null 或 undefined 返回 b
!!a 将 a 转为 布尔值 true 或 false

场景选择建议:

需求 推荐操作符
"只要不是 null/undefined 就用原值" ✅ ??
"只要是 falsy(包括空字符串、0)就用默认值" `
"判断某个值是否存在(转布尔)" ✅ !!

💡 实际应用示例

复制代码

js

编辑

复制代码
const config = {
  timeout: 0,
  retries: null,
  name: ""
};

// 错误:timeout 会被设为 5000(因为 0 是 falsy)
const timeout1 = config.timeout || 5000; // 5000 ❌

// 正确:只在 timeout 为 null/undefined 时设默认值
const timeout2 = config.timeout ?? 5000; // 0 ✅

// 判断用户是否设置了名字(即使为空字符串也算"设置了")
const hasName = !!config.name; // true(因为 "" 存在,只是空)

✅ 总结口诀:

  • !!x → "x 是真还是假?"
  • a || b → "a 有没有值?没有就用 b" (把 0、"" 当"没有")
  • a ?? b → "a 是 null/undefined 吗?是就用 b"(更精准的默认值)

📌 现代 JS 开发中,优先使用 ?? 设置默认值,避免 || 的陷阱!

支持情况:?? 自 ES2020 起支持,所有现代浏览器和 Node.js 14+ 均可用。

相关推荐
WebInfra25 分钟前
Rspack 2.3 发布:联手 SWC 团队带来全新编译器
前端·javascript·github
小卿噢1 小时前
同样是插 10 万行,最快的写法比最慢的快 103 倍
前端
weixin_417396831 小时前
星级酒店境外电视频道怎么合法接入?合规要点与核对清单
开发语言·前端·php·1024程序员节·综合布线
hiahiahia1232 小时前
Structured Output
前端·人工智能
FRing032 小时前
JavaScript入门到精通三十一(原型继承、原型链)
开发语言·前端·javascript
程序员大阳2 小时前
副队长JavaScript教程(52)-DOM操作元素的内容
javascript·dom·innertext·innerhtml·value·内容操作
山雀~3 小时前
CSP 安全漏洞修复
前端·网络协议
裕波3 小时前
苏千|从 cnpm 到 Vite+:AI 时代的开发者体验演进
javascript
console.log('npc')3 小时前
周期任务功能完整实现:CRON 编辑器 + 模板变量 + 执行历史
javascript·vue.js·编辑器
程序员大阳4 小时前
副队长JavaScript教程(58)-基于DOM的网页留言板开发
javascript·实例·dom·案例·留言板