09.JavaScript 比较运算符与逻辑运算符

09.JavaScript 比较运算符与逻辑运算符

📋 速查对照表

比较运算符

运算符 名称 描述 示例 结果
== 等于 值相等就返回 true 5 == "5" true
=== 严格等于 值和类型都相等才返回 true 5 === "5" false
!= 不等于 值不相等就返回 true 5 != "5" false
!== 严格不等于 值或类型不相等就返回 true 5 !== "5" true
> 大于 左边大于右边返回 true 10 > 5 true
< 小于 左边小于右边返回 true 10 < 5 false
>= 大于等于 左边大于或等于右边返回 true 5 >= 5 true
<= 小于等于 左边小于或等于右边返回 true 5 <= 3 false

逻辑运算符

运算符 名称 描述 示例 结果
&& 逻辑与 两边都为 true 才返回 true true && false false
|| 逻辑或 至少一边为 true 就返回 true true || false true
! 逻辑非 把 true 变 false,false 变 true !true false
?? 空值合并 左边是 null/undefined 就返回右边 null ?? "默认" "默认"
?. 可选链 安全地访问对象属性 user?.name 不会报错

一、比较运算符

1. == 等于(宽松相等)

比较值是否相等,如果类型不同会自动转换类型再比较。

console.log(5 == 5);        // true
console.log(5 == "5");      // true(字符串"5"转成数字5)
console.log(true == 1);     // true(true转成1)
console.log(false == 0);    // true(false转成0)
console.log(null == undefined); // true

2. === 严格等于(推荐使用)

值和类型都必须相等。

console.log(5 === 5);        // true
console.log(5 === "5");      // false(类型不同)
console.log(true === 1);     // false(类型不同)
console.log(false === 0);    // false(类型不同)
console.log(null === undefined); // false(类型不同)

3. != 不等于(宽松)

console.log(5 != 3);        // true(值不相等)
console.log(5 != "5");      // false(值相等)
console.log(true != 1);     // false(值相等)

4. !== 严格不等于(推荐使用)

console.log(5 !== 3);        // true
console.log(5 !== "5");      // true(类型不同)
console.log(true !== 1);     // true(类型不同)

5. > 大于

console.log(10 > 5);        // true
console.log(5 > 10);        // false
console.log("10" > "5");    // true(字符串比较第一个字符)
console.log("abc" > "abd"); // false(逐字符比较,'c' < 'd')

6. < 小于

console.log(5 < 10);        // true
console.log(10 < 5);        // false
console.log("apple" < "banana"); // true(a在b前面)

7. >= 大于等于

console.log(5 >= 5);        // true(等于)
console.log(10 >= 5);       // true(大于)
console.log(3 >= 5);        // false

8. <= 小于等于

console.log(5 <= 5);        // true(等于)
console.log(3 <= 5);        // true(小于)
console.log(10 <= 5);       // false

二、逻辑运算符

1. && 逻辑与(AND)

// 两个条件都为 true,结果才是 true
console.log(true && true);    // true
console.log(true && false);   // false
console.log(false && true);   // false
console.log(false && false);  // false

// 实际应用:检查多个条件
let age = 25;
let hasLicense = true;

if (age >= 18 && hasLicense) {
    console.log("可以开车");  // 执行
}

// 短路特性:如果第一个为 false,就不会看第二个
let x = 0;
console.log(false && (x++));  // false(x++不会执行)
console.log(x);               // 0(x没有增加)

2. || 逻辑或(OR)

// 至少一个条件为 true,结果就是 true
console.log(true || true);    // true
console.log(true || false);   // true
console.log(false || true);   // true
console.log(false || false);  // false

// 实际应用:提供默认值
let username = "";
let displayName = username || "游客";
console.log(displayName);     // "游客"

// 短路特性:如果第一个为 true,就不会看第二个
let y = 0;
console.log(true || (y++));   // true(y++不会执行)
console.log(y);               // 0(y没有增加)

3. ! 逻辑非(NOT)

// 取反:true 变 false,false 变 true
console.log(!true);           // false
console.log(!false);          // true
console.log(!0);              // true(0转成false,再取反)
console.log(!"hello");        // false(非空字符串转成true,再取反)

// 双重否定:转成布尔值
console.log(!!5);             // true
console.log(!!0);             // false
console.log(!!"");            // false

4. ?? 空值合并运算符(ES2020)

// 只有左边是 null 或 undefined 时才返回右边
console.log(null ?? "默认值");      // "默认值"
console.log(undefined ?? "默认值"); // "默认值"
console.log(0 ?? "默认值");         // 0(不是null/undefined)
console.log("" ?? "默认值");        // ""(不是null/undefined)
console.log(false ?? "默认值");     // false(不是null/undefined)

// 与 || 的区别
console.log(0 || "默认");      // "默认"(0被当作false)
console.log(0 ?? "默认");      // 0(0不是null/undefined)
console.log("" || "默认");     // "默认"(空字符串被当作false)
console.log("" ?? "默认");     // ""(空字符串不是null/undefined)

5. ?. 可选链运算符(ES2020)

// 安全地访问嵌套对象属性
let user = {
    name: "张三",
    address: {
        city: "北京"
    }
};

// 传统写法(繁琐)
let city1 = user && user.address && user.address.city;

// 可选链写法(简洁)
let city2 = user?.address?.city;
console.log(city2);  // "北京"

// 如果属性不存在,返回undefined而不是报错
console.log(user?.contact?.phone);  // undefined(不会报错)

// 也可以用于方法调用
let obj = {
    greet: function() { return "Hello"; }
};
console.log(obj.greet?.());  // "Hello"
console.log(obj.sayHi?.());  // undefined(不会报错)

三、特殊比较规则

1. NaN 的特殊性

// NaN 不等于任何值,包括它自己
console.log(NaN == NaN);     // false
console.log(NaN === NaN);    // false

// 使用 isNaN() 或 Number.isNaN() 判断
console.log(isNaN(NaN));            // true
console.log(Number.isNaN(NaN));     // true
console.log(Number.isNaN("abc"));   // false(传统isNaN会返回true)

2. null 和 undefined 的比较

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

3. 字符串和数字比较

// 字符串会先转成数字再比较
console.log("5" == 5);       // true
console.log("5" === 5);      // false
console.log("10" > "5");     // true(比较第一个字符"1" > "5"?不,这里比较数值)
console.log("10" > 5);       // true(字符串"10"转成数字10)

// 注意:如果字符串不能转成数字,会变成NaN
console.log("abc" > 5);      // false("abc"转成NaN,NaN与任何比较都是false)

四、组合使用示例

1. 复杂条件判断

let age = 25;
let hasLicense = true;
let hasCar = false;

// 可以开车去上班的条件
let canDriveToWork = age >= 18 && hasLicense && hasCar;
console.log(canDriveToWork);  // false(没有车)

// 可以学车的条件
let canLearnDrive = age >= 18 && !hasLicense;
console.log(canLearnDrive);   // false(已经有驾照了)

// 打折条件:学生或老年人
let isStudent = true;
let isSenior = false;
let discount = isStudent || isSenior;
console.log(discount);        // true

2. 表单验证

function validateForm(username, password, email) {
    // 所有条件都必须满足
    let isValid = 
        username.length >= 3 &&  // 用户名至少3位
        password.length >= 6 &&  // 密码至少6位
        email.includes("@") &&   // 邮箱必须包含@
        email.includes(".");     // 邮箱必须包含.

    return isValid;
}

console.log(validateForm("张三", "123456", "test@qq.com"));  // true

3. 权限检查

let user = {
    isAdmin: false,
    isVIP: true,
    credits: 100
};

// VIP用户或管理员可以访问
let canAccess = user.isAdmin || user.isVIP;
console.log(canAccess);  // true

// 有足够积分且不是管理员(防止管理员刷分)
let canBuy = user.credits >= 50 && !user.isAdmin;
console.log(canBuy);     // true

五、运算符优先级

优先级从高到低

// 1. 小括号 () - 最高优先级
// 2. 逻辑非 !
// 3. 比较运算符 >, <, >=, <=, ==, !=, ===, !==
// 4. 逻辑与 &&
// 5. 逻辑或 ||
// 6. 空值合并 ??

使用括号明确优先级

// 混淆的表达式
let result1 = true || false && false;
console.log(result1);  // true(&&优先级高于||,先算false&&false=false,再算true||false=true)

// 使用括号明确意图
let result2 = (true || false) && false;
console.log(result2);  // false(先算true||false=true,再算true&&false=false)

// 推荐的写法:复杂表达式加括号
let age = 20;
let isStudent = true;
let hasDiscount = (age < 18 || age >= 65) && isStudent;

六、短路运算的实际应用

1. 条件执行

let isLoggedIn = true;

// 如果用户已登录,才执行函数
isLoggedIn && console.log("显示用户菜单");

// 相当于:
if (isLoggedIn) {
    console.log("显示用户菜单");
}

2. 设置默认值

function greet(name) {
    // 如果name不存在,使用默认值
    name = name || "朋友";
    console.log(`你好,${name}!`);
}

greet("张三");  // "你好,张三!"
greet();        // "你好,朋友!"

// 更好的写法(ES2020):
function greetBetter(name) {
    name = name ?? "朋友";
    console.log(`你好,${name}!`);
}

3. 链式调用保护

// 传统写法
function getCity(user) {
    if (user && user.address && user.address.city) {
        return user.address.city;
    }
    return "未知";
}

// 使用可选链(简洁)
function getCityModern(user) {
    return user?.address?.city ?? "未知";
}

七、常见错误与注意事项

1. 使用 === 而不是 ==

// ❌ 容易出现意外结果
console.log(0 == false);      // true(可能不是想要的结果)
console.log("" == false);     // true
console.log([] == false);     // true

// ✅ 使用严格比较
console.log(0 === false);     // false(更清晰)
console.log("" === false);    // false
console.log([] === false);    // false

2. 注意浮点数精度

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

// 解决方法:设置误差范围
function floatEqual(a, b) {
    return Math.abs(a - b) < 0.000001;
}
console.log(floatEqual(0.1 + 0.2, 0.3));  // true

3. 理解短路特性

let count = 0;

// ❌ 可能达不到预期效果
function increment() {
    return count++;
}

// 因为短路,increment()不会执行
console.log(false && increment());
console.log(count);  // 0(没有增加)

// ✅ 明确想要的效果
if (false) {
    increment();
}

4. 避免过度嵌套

// ❌ 难以阅读
if (user && user.profile && user.profile.settings && user.profile.settings.theme === "dark") {
    // ...
}

// ✅ 使用可选链
if (user?.profile?.settings?.theme === "dark") {
    // ...
}

// ✅ 或者提取变量
const theme = user?.profile?.settings?.theme;
if (theme === "dark") {
    // ...
}

八、练习题

练习1:判断成绩等级

function getGrade(score) {
    if (score >= 90) return "A";
    if (score >= 80) return "B";
    if (score >= 70) return "C";
    if (score >= 60) return "D";
    return "F";
}

console.log(getGrade(85));  // "B"
console.log(getGrade(55));  // "F"

练习2:检查用户名合法性

function isValidUsername(username) {
    // 要求:长度3-10,只能包含字母和数字
    const minLength = 3;
    const maxLength = 10;
    const regex = /^[A-Za-z0-9]+$/;

    return username.length >= minLength && 
           username.length <= maxLength && 
           regex.test(username);
}

console.log(isValidUsername("abc123"));  // true
console.log(isValidUsername("ab"));      // false(太短)
console.log(isValidUsername("abc123!@#")); // false(有特殊字符)

练习3:三元运算符(条件运算符)

// 语法:条件 ? 值1 : 值2
let age = 20;
let status = age >= 18 ? "成人" : "未成年";
console.log(status);  // "成人"

// 嵌套三元运算符(不建议,可读性差)
let score = 85;
let grade = score >= 90 ? "A" : 
            score >= 80 ? "B" : 
            score >= 70 ? "C" : 
            score >= 60 ? "D" : "F";
console.log(grade);  // "B"

九、总结口诀

比较运算符比大小,==宽松===严格。
!=宽松!==严格,>大于<小于。
>=小于等于,<=大于等于。

逻辑运算符有三个,&&与、||或、!非。
&&两边真才真,||一边真就真。
!是取反真变假,短路特性效率高。

??空值合并运算符,null/undefined用默认。
?.可选链运算符,安全访问不报错。

记住优先级,复杂加括号。
多用严格等,避免类型转换坑。

最佳实践建议

  1. 始终使用 ===!==
  2. 利用短路特性简化代码
  3. 使用可选链 ?. 避免属性访问错误
  4. 使用空值合并 ?? 设置默认值
  5. 复杂表达式用括号明确优先级
  6. 避免深度嵌套,提取变量提高可读性

掌握了比较和逻辑运算符,你就有了JavaScript中最重要的决策工具!🎯

shi著
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇