JavaScript 中的运算符分类:单目、双目、三目(以及极少数的多目)
JavaScript 的运算符按照参与运算的操作数数量可以分为以下几类:
| 分类 | 操作数数量 | 英文名称 | 常见中文叫法 | 代表性运算符示例 | 占比(日常使用频率) |
|---|---|---|---|---|---|
| 单目运算符 | 1 个 | Unary Operators | 一元运算符 / 单目 | ! – + ~ typeof void delete ++ — | ★★★★★ |
| 双目运算符 | 2 个 | Binary Operators | 二元运算符 / 双目 | + – * / % ** & | ^ << >> >>> == === != !== && || , |
| 三目运算符 | 3 个 | Ternary Operator | 三元运算符 / 条件运算符 | 条件 ? 表达式1 : 表达式2 | ★★★★ |
| 多目运算符 | >3 个 | N-ary / Multiary | 多目运算符 | 几乎没有,唯一接近的是 , 运算符的连续使用 | ★☆☆☆☆ |
1. 单目运算符(Unary Operators)详解
单目运算符只作用于一个操作数,根据位置分为前置和后置两种。
| 运算符 | 名称 | 作用 | 示例 | 返回值说明 |
|---|---|---|---|---|
+ | 一元正号 | 转换为数字(常用于字符串转数字) | + “123” → 123 + “abc” → NaN | number |
- | 一元负号 | 取负(同时转换为数字) | – “5” → -5 | number |
! | 逻辑非 | 取反(先转为布尔值再取反) | !true → false !!”hello” → true | boolean |
~ | 按位非(NOT) | 按位取反(32位有符号整数) | ~5 → -6 | number(整数) |
typeof | 类型判断 | 返回操作数的类型字符串 | typeof null → “object” | string |
void | 求值但丢弃结果 | 执行表达式但返回 undefined(常用于 <a href="javascript:void(0)">) | void(0) → undefined | undefined |
delete | 删除属性 | 删除对象属性(成功返回 true,失败/不存在返回 false) | delete obj.x | boolean |
++ / -- | 自增/自减 | 前置:先运算后返回值 后置:先返回值后运算 | let a=5; b=++a; → a=6,b=6 | number |
最容易混淆的点:
let a = 10;
console.log(++a); // 11 先+1再用
console.log(a++); // 11 先用再+1
console.log(a); // 12
2. 双目运算符(Binary Operators)——最常用的一类
这是日常写代码出现频率最高的运算符,几乎占了 80% 以上。
| 类别 | 运算符 | 备注 / 特殊行为 |
|---|---|---|
| 算术 | + - * / % ** | ** 是 ES2016 引入的幂运算符+ 有字符串拼接特性 |
| 比较(关系) | < > <= >= instanceof in | in 用于判断属性是否存在 |
| 等值 | == != === !== | 强烈推荐始终使用 === 和 !==(严格相等) |
| 位运算 | & | ^ ~ << >> >>> | >>> 是无符号右移(JavaScript 唯一无符号位移) |
| 逻辑 | && || ?? | ?? 是空值合并运算符(ES2020)&& 和 || 有短路特性 |
| 赋值 | = += -= *= /= %= **= <<= >>= >>>= &= |= ^= | 复合赋值都是先计算再赋值 |
| 逗号 | , | 从左到右求值,返回最右边的值(常用于 for 循环初始化多个变量) |
短路特性(非常重要):
false && doSomething() // doSomething 永远不会执行
true || doSomething() // doSomething 永远不会执行
// 常用写法
const name = user?.name || "匿名";
const price = input ?? 0; // 只在 null/undefined 时才用默认值
3. 三目运算符(Ternary Operator)——唯一合法的三目运算符
语法:
条件 ? 表达式1(true时执行) : 表达式2(false时执行)
const status = age >= 18 ? "成人" : "未成年";
// 嵌套(不建议嵌套超过 2 层,可读性极差)
const msg = score >= 90 ? "优秀" : score >= 60 ? "及格" : "不及格";
替代方案(现代写法):
// 更清晰的写法(推荐)
const grade = (() => {
if (score >= 90) return "优秀";
if (score >= 60) return "及格";
return "不及格";
})();
4. 真正意义上的“多目运算符”在 JavaScript 中几乎不存在
JavaScript 没有像 C 语言那样的多目运算符(例如 a ? b : c ? d : e 仍然是嵌套的三目)。
唯一有点“多目”感觉的是逗号运算符的连续使用:
let a = 1, b = 2, c = 3; // 声明时
(a = 10, b = 20, c = 30); // 表达式中,返回最后一个值 → 30
但严格来说,它仍然是多个双目逗号运算符的组合,不是真正的多目运算符。
快速记忆口诀
- 1 个操作数 → 单目(! – + ~ typeof void delete ++ –)
- 2 个操作数 → 双目(绝大多数:+ – * / % ** && || == === …)
- 3 个操作数 → 三目(只有
?:) - >3 个 → 几乎没有(逗号运算符是“伪多目”)
面试/代码审查常考对比题
console.log(+""); // 0
console.log(+[]); // 0
console.log(+{}); // NaN
console.log([] + {}); // "[object Object]"
console.log({} + []); // 0 ({} 被当成代码块)
console.log(1 + -"2" + "3"); // "1-23" → "-23"
你目前写代码中最常混淆或最想搞清楚的运算符是哪一个?
==vs===??vs||void 0的真实用途- 位运算(& | ^ ~ << >> >>>)
- 逗号运算符的边界用法
可以告诉我,我再针对性展开更详细的例子和陷阱。