JavaScript 运算符

运算符是连接值的"动词":加号、等号、比较大小、判断真假。这一章我们系统过一遍 JS 的所有运算符,重点讲清楚 ===== 的区别——这是 JS 代码质量的第一条军规。

1. 算术运算符

最基本的数学运算。JS 不区分整数除法和浮点除法,7 / 2 直接得 3.5:

// 算术运算符:+ - * / % **
console.log(7 + 3);    // 10
console.log(7 - 3);    // 4
console.log(7 * 3);    // 21
console.log(7 / 2);    // 3.5(JS 除法结果是小数,不会取整)
console.log(7 % 3);    // 1(取余/取模)
console.log(2 ** 10);  // 1024(幂运算,ES2016)

// 自增 ++ / 自减 --
let i = 1;
console.log(i++);  // 1(先用后加)
console.log(i);    // 2
console.log(++i);  // 3(先加后用)
console.log(i--);  // 3
console.log(i);    // 2

// 数值取整技巧
console.log(5 / 2 | 0);      // 2(位运算取整,只对 32 位整数有效)
console.log(Math.floor(5 / 2)); // 2(推荐写法)

++-- 有"前置"和"后置"两种:前置 ++i 先加后用,后置 i++ 先用后加。新手容易混淆,实际开发建议直接写 i = i + 1i += 1,更清晰。

2. 比较运算符:== vs ===

这是 JS 最重要的一节。务必用 ===(严格相等),不要用 ==(松散相等)。区别在于:

// 比较运算符:> < >= <= == != === !==
console.log(3 > 2);       // true
console.log(3 < 2);       // false
console.log(3 >= 3);      // true
console.log(3 <= 4);      // true

// ⚠️ == 与 === 的核心区别
// ==   会做类型转换再比较(容易出 bug)
// ===  严格相等,类型不同直接 false(推荐)

console.log(1 == "1");    // true(字符串转数字)
console.log(1 === "1");   // false
console.log(0 == false);  // true
console.log(0 === false); // false
console.log(null == undefined);  // true
console.log(null === undefined); // false
console.log(NaN == NaN);  // false ⚠️ NaN 连自己都不等!

// 字符串比较:按字典序 Unicode
console.log("apple" < "banana");  // true
console.log("10" < "9");          // true(逐字符比较,'1' < '9')

记住这条规则:写 === 不写 ==,写 !== 不写 !=。仅一种例外——判断 null/undefined 时,可以用 x == null(它等价于 x === null || x === undefined,简洁)。

3. 逻辑运算符与短路求值

JS 的 &&|| 有一个特别之处:返回的不一定是布尔值,而是"求值停止时"的那个操作数。这就是短路求值:

// 逻辑运算符:&& || !
console.log(true && false);  // false(且:两边都真才真)
console.log(true || false);  // true(或:一边真就真)
console.log(!true);          // false(非:取反)

// 短路求值:&& 遇到假就停,|| 遇到真就停,返回的是"停下来的值"而非布尔
const user = null;
console.log(user && user.name);   // null(user 是假,直接返回,不求 user.name)

const name = "";
const displayName = name || "匿名";  // "匿名"(name 是空字符串,假值)
console.log(displayName);

// ?? 空值合并:只在 null/undefined 时取右侧(更精确)
const count = 0;
console.log(count || 10);    // 10(0 是假值)
console.log(count ?? 10);    // 0(0 不是 null/undefined,保留)

// ! 用作布尔转换
const hasItems = !!"hello";   // true(双感叹号转布尔)

短路求值在实战中极其常用:

4. 三元运算符

三元运算符是表达式版的 if-else:一行搞定简单的条件赋值:

// 三元(三目)运算符:条件 ? 真值 : 假值
const age = 20;
const result = age >= 18 ? "成年" : "未成年";
console.log(result);  // 成年

// 可以嵌套(但可读性差,慎用)
const score = 78;
const grade = score >= 90 ? "A"
            : score >= 80 ? "B"
            : score >= 60 ? "C"
            : "D";
console.log(grade);  // C

// 实战:根据条件选值
const greeting = (hour) =>
  hour < 12 ? "早上好" : hour < 18 ? "下午好" : "晚上好";
console.log(greeting(10));  // 早上好
console.log(greeting(20));  // 晚上好

三元是表达式(有返回值),if-else语句(没有返回值)。需要赋值的简单分支用三元更简洁,复杂逻辑还是用 if-else 更清楚。不要嵌套超过两层,可读性会骤降。

5. 赋值运算符

赋值运算符是 =,加上 +=-= 等复合形式:

// 赋值运算符:= += -= *= /= %=
let n = 10;
n += 5;    // 等价于 n = n + 5;  现在 n = 15
n -= 3;    // n = 12
n *= 2;    // n = 24
n /= 4;    // n = 6
n %= 4;    // n = 2
n **= 3;   // n = 8

// 链式赋值(从右到左)
let a, b, c;
a = b = c = 5;
console.log(a, b, c);  // 5 5 5

6. 字符串运算符

字符串主要用 + 拼接。但注意运算顺序——一旦遇到字符串,后面的数字也会被转成字符串:

// 字符串运算:主要是 + 拼接
console.log("Hello" + " " + "World");  // Hello World

// 任意类型 + 字符串 = 字符串(注意顺序)
console.log("答案:" + 42);     // "答案:42"
console.log(1 + 2 + "3");      // "33"(先算 1+2=3,再拼 "3")
console.log("1" + 2 + 3);      // "123"(从左到右,1+2="12",+3="123")

// 推荐用模板字符串,清晰且支持表达式
const name = "小明";
const age = 20;
console.log(`姓名:${name},年龄:${age}`);  // 姓名:小明,年龄:20

混拼字符串和数字时,推荐始终用模板字符串(反引号 + ${}),不再有顺序歧义。

7. 一元运算符

// typeof:返回类型字符串
console.log(typeof 42);       // "number"
console.log(typeof "hi");     // "string"
console.log(typeof undefined); // "undefined"
console.log(typeof null);     // "object"

// !:逻辑取反(返回布尔)
console.log(!false);          // true

// +x:转数字
console.log(+"42");           // 42
console.log(+"");             // 0
console.log(+"abc");          // NaN

// -x:取负
console.log(-5);              // -5
console.log(-"3");            // -3

// delete:删除对象属性
const obj = { a: 1, b: 2 };
delete obj.a;
console.log(obj);             // { b: 2 }

// void:求值后返回 undefined
console.log(void 0);          // undefined

8. 运算符优先级(从高到低)

优先级决定运算顺序。常用优先级:

  1. () 括号(最高,可以强制改顺序)
  2. .[]() 成员访问、函数调用
  3. !-(一元)、++typeof
  4. **
  5. */%
  6. +-
  7. <<=>>=instanceofin
  8. ==!====!==
  9. &&
  10. ||??
  11. ?: 三元
  12. =+= 等赋值

记不住没关系——拿不准就加括号。括号既能让意图明确,也避免依赖隐式优先级。

小结

下一篇我们看条件语句和循环——让程序真正能"做判断、重复干活"。

← 上一篇 JavaScript 数据类型

下一篇 JavaScript 条件与循环

✈️💬