Skip to content

09|JavaScript 运算符与表达式

变量声明之后,需要对数据进行计算和比较。运算符是 JavaScript 执行这些操作的基本工具:算术运算、比较大小、逻辑判断、字符串拼接。理解每个运算符的行为和优先级,才能写出预期之内的表达式。

一、算术运算符

js
const a = 10;
const b = 3;

console.log(a + b);    // 13,加法
console.log(a - b);    // 7,减法
console.log(a * b);    // 30,乘法
console.log(a / b);    // 3.333...,除法
console.log(a % b);    // 1,取余(10 除以 3 余 1)
console.log(a ** b);   // 1000,幂运算(10 的 3 次方)

自增与自减

js
let n = 5;

console.log(n++);   // 输出 5,然后 n 变为 6(后置:先返回值,再自增)
console.log(++n);   // n 先变为 7,然后输出 7(前置:先自增,再返回值)

自增/自减会修改变量本身的值。在复杂表达式中混用前置和后置容易出错,建议单独成行:

js
// 不推荐
const result = arr[i++];

// 推荐
const result = arr[i];
i++;

二、比较运算符

js
console.log(5 == "5");     // true(== 做类型转换后比较)
console.log(5 === "5");    // false(=== 类型不同直接不相等)
console.log(5 != "5");     // false
console.log(5 !== "5");    // true

console.log(3 > 2);        // true
console.log(3 >= 3);       // true
console.log(3 < 2);        // false
console.log(3 <= 2);       // false
运算符含义是否做类型转换
==相等
===严格相等
!=不相等
!==严格不相等

始终使用 ===!==== 的转换规则复杂且容易踩坑:

js
console.log(0 == "");       // true
console.log(0 == "0");      // true
console.log("" == "0");     // false
console.log(null == undefined);  // true
console.log(null === undefined); // false

三、逻辑运算符

js
const isAdmin = true;
const isActive = false;

console.log(isAdmin && isActive);   // false(与:两边都为 true 才为 true)
console.log(isAdmin || isActive);    // true(或:一边为 true 即为 true)
console.log(!isAdmin);               // false(非:取反)

短路求值

逻辑运算符会"短路"——一旦结果确定,不再计算后面的表达式:

js
// &&:左边为 false,右边不执行
const result1 = false && someFunction();   // someFunction 不会调用

// ||:左边为 true,右边不执行
const result2 = true || someFunction();     // someFunction 不会调用

利用短路求值设置默认值:

js
function greet(name) {
  const actualName = name || "访客";   // name 为 falsy 时用默认值
  console.log(`你好,${actualName}`);
}

greet("张三");     // "你好,张三"
greet("");         // "你好,访客"(空字符串是 falsy)
greet(null);       // "你好,访客"

现代 JavaScript 更推荐用空值合并运算符 ??,它只判断 nullundefined,不判断其他 falsy 值:

js
const port = config.port ?? 8080;   // port 为 0 时仍然用 0,不会 fallback 到 8080

四、赋值运算符

js
let x = 10;

x += 5;    // x = x + 5,x 变为 15
x -= 3;    // x = x - 3,x 变为 12
x *= 2;    // x = x * 2,x 变为 24
x /= 4;    // x = x / 4,x 变为 6
x %= 4;    // x = x % 4,x 变为 2

五、字符串拼接

js
const host = "web-01";
const domain = "example.com";

// + 运算符拼接
const fqdn = host + "." + domain;     // "web-01.example.com"

// 模板字符串(推荐)
const url = `https://${domain}/api`;   // "https://example.com/api"

+ 运算符在字符串和数字混用时容易出意外:

js
console.log("端口: " + 8080);     // "端口: 8080"(数字转字符串)
console.log("10" + 5);            // "105"(拼接)
console.log("10" - 5);            // 5(字符串转数字)
console.log(10 + 5 + "px");       // "15px"
console.log("px" + 10 + 5);       // "px105"

运算从左到右进行。第一例先算 10 + 5 = 15,再和 "px" 拼接;第二例先算 "px" + 10 = "px10",再和 5 拼接。

六、运算符优先级

js
const result = 2 + 3 * 4;       // 14,不是 20(乘法优先级高于加法)
const result2 = (2 + 3) * 4;    // 20,括号改变优先级

常见优先级(从高到低):

优先级运算符
最高括号 ()
自增/自减 ++--
乘除取余 */%
加减 +-
比较 ><===
逻辑与 &&
更低逻辑或 ||
最低赋值 =

记不清优先级时,用括号显式分组——代码可读性比少敲几个字符重要得多。

七、常见错误

== 与 === 混用

js
// 错误
if (status == "active") {   // 可能因类型转换产生意外结果

// 正确
if (status === "active") {  // 类型和值都匹配才通过

浮点数精度问题

js
console.log(0.1 + 0.2 === 0.3);   // false

// 解决方案:先乘成整数运算,再除回去
console.log((0.1 * 10 + 0.2 * 10) / 10 === 0.3);   // true

逻辑与和逻辑或优先级混淆

js
// 意图:端口是 80 或 443 时通过
if (port === 80 || port === 443) {   // 正确

// 错误
if (port === 80 || 443) {            // 443 是 truthy,条件永远为 true

字符串和数字的隐式转换

js
const input = document.getElementById("port").value;   // 输入框的值是字符串
const newPort = input + 10;   // "8080" + 10 = "808010",不是 8090

// 正确:先转数字
const newPort = Number(input) + 10;   // 8090