Appearance
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 更推荐用空值合并运算符 ??,它只判断 null 和 undefined,不判断其他 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