逻辑运算符
2024年12月6日大约 5 分钟
JavaScript 的逻辑运算符是语言中非常强大且灵活的特性,它们不仅可以进行布尔逻辑运算,还能在很多场景下进行巧妙的逻辑控制和值选择。让我们深入探讨这些运算符的用法和特性。
基本逻辑运算符
JavaScript 有三种主要的逻辑运算符:&&(与)、||(或)和 !(非)。
1. 与运算符 &&
// 基本布尔运算
console.log(true && true); // 输出:true
console.log(true && false); // 输出:false
console.log(false && true); // 输出:false
console.log(false && false); // 输出:false
// 短路求值(Short-circuit evaluation)
let name = "张三";
let age = 25;
// 只有当 name 和 age 都为真时,才会执行后面的代码
name && age && console.log("条件满足");2. 或运算符 ||
// 基本布尔运算
console.log(true || false); // 输出:true
console.log(false || true); // 输出:true
console.log(false || false); // 输出:false
// 默认值设置
function greet(name) {
// 如果没有传入名字,使用默认值
name = name || "游客";
console.log(`你好,${name}!`);
}
greet(); // 输出:你好,游客!
greet("小明"); // 输出:你好,小明!3. 非运算符 !
// 取反操作
console.log(!true); // 输出:false
console.log(!false); // 输出:true
// 双重非运算(转换为布尔值)
console.log(!!1); // 输出:true
console.log(!!0); // 输出:false
console.log(!!{}); // 输出:true
console.log(!!""); // 输出:false高级用法和技巧
逻辑运算符的值选择
// 与运算符(&&)可以用于条件选择
let result = true && "Hello"; // 结果是 "Hello"
let result2 = false && "Hello"; // 结果是 false
// 或运算符(||)可以选择第一个真值
let name = "" || "张三" || "李四"; // 结果是 "张三"组合使用
// 复杂的逻辑组合
function checkUser(user) {
return user && user.isActive && user.hasPermission;
}
// 多条件检查
let isEligible = (age > 18) && (hasLicense) && (passedTest);逻辑运算符的求值规则
&&(与):- 从左到右计算
- 如果第一个操作数为假,直接返回第一个操作数
- 如果第一个操作数为真,返回第二个操作数
||(或):- 从左到右计算
- 如果第一个操作数为真,直接返回第一个操作数
- 如果第一个操作数为假,返回第二个操作数
实际应用场景
// 条件渲染
function renderUserInfo(user) {
return user && (
<div>
<p>姓名:{user.name}</p>
<p>年龄:{user.age}</p>
</div>
);
}
// 安全访问嵌套属性
let city = user && user.address && user.address.city;
// 等同于现代的可选链写法:let city = user?.address?.city;
// 复杂的条件逻辑
function processPayment(user, amount) {
return (
user.isVerified &&
user.balance >= amount &&
performTransaction(user, amount)
);
}思考和进阶
为了加深理解,你可以思考以下问题:
- 为什么
0 && "Hello"会返回0? "Hello" || 0为什么会返回"Hello"?- 如何利用这些特性编写更简洁的代码?
小技巧和注意事项
- 逻辑运算符不仅限于布尔值,可以处理任何类型的值
- 理解"真值"和"假值"的概念很重要
- 可以利用短路求值简化代码
- 在复杂条件中注意可读性
拓展:现代 JavaScript 中的逻辑运算
可选链操作符 ?.
// 安全访问嵌套属性
let userName = user?.profile?.name;
// 安全调用方法
user?.login?.();空值合并运算符 ??
// 只有在左侧为 null 或 undefined 时才使用右侧值
let username = inputName ?? "默认用户名";运算符优先级概述
运算符优先级是 JavaScript 中一个非常重要且容易被忽视的概念。让我们系统地深入探讨这个话题,帮助你全面理解运算符的执行顺序。
运算符优先级决定了在表达式中不同运算符的求值顺序。优先级高的运算符会先于优先级低的运算符被计算。
优先级层级(从高到低)
1. 分组运算符
// 括号具有最高优先级,可以改变默认的运算顺序
let result = (2 + 3) * 4; // 先计算括号内容
console.log(result); // 输出 202. 成员访问和函数调用
let obj = {
value: 10,
method() { return this.value; }
};
console.log(obj.method()); // 成员访问和函数调用优先级很高3. 一元运算符
// 一元运算符具有很高的优先级
let x = 5;
let y = -x; // 取负运算
let z = !true; // 逻辑非4. 算术运算符
// 乘法和除法优先于加法和减法
let result = 2 + 3 * 4; // 先计算 3 * 4,再加 2
console.log(result); // 输出 145. 关系运算符
// 关系运算符有特定的优先级顺序
let isTrue = 5 > 3 && 2 < 4;
console.log(isTrue); // 输出 true6. 逻辑运算符
// 逻辑与 (&&) 优先于逻辑或 (||)
let complexLogic = true || false && false;
console.log(complexLogic); // 输出 true详细的优先级表(部分)
| 优先级 | 运算符类型 | 运算符 |
|---|---|---|
| 20 | 分组 | () |
| 19 | 成员访问 | ., [] |
| 18 | 函数调用 | () |
| 17 | 后置递增/递减 | x++, x-- |
| 16 | 逻辑非, 一元加/减 | !, +, -, typeof, void, delete |
| 15 | 前置递增/递减 | ++x, --x |
| 14 | 乘法/除法 | *, /, % |
| 13 | 加法/减法 | +, - |
| 12 | 关系运算符 | <, >, <=, >=, instanceof, in |
| 11 | 相等性 | ==, !=, ===, !== |
| 6 | 逻辑与 | && |
| 5 | 逻辑或 | ` |
| 3 | 条件运算符 | ?: |
复杂示例
let result = 2 + 3 * 4 - (6 / 2) + !false;
// 执行顺序:
// 1. (6 / 2) => 3
// 2. !false => true (转换为 1)
// 3. 3 * 4 => 12
// 4. 2 + 12 - 3 + 1 => 12
console.log(result); // 输出 12实践建议
- 当不确定运算顺序时,使用括号明确优先级
- 复杂表达式尽量拆分,提高代码可读性
- 了解运算符优先级,但不要过度依赖
思考练习
尝试预测以下表达式的结果:
let x = 5;
let result = x++ + ++x * 2;
console.log(result); // 你能准确预测吗?常见陷阱
// 类型转换可能影响优先级
console.log(true + false); // 1
console.log(true == 1); // true
console.log(true === 1); // false