比较运算符 #
一、运算符概述 #
比较运算符用于比较两个值,返回布尔值(true或false)。理解比较运算符对于条件判断至关重要。
二、相等比较 #
2.1 相等运算符(==) #
宽松相等,会进行类型转换:
typescript
console.log(1 == 1); // true
console.log(1 == "1"); // true (类型转换)
console.log(0 == false); // true
console.log("" == false); // true
console.log(null == undefined); // true
// 数组和对象比较引用
console.log([] == []); // false
console.log({} == {}); // false
const arr = [];
console.log(arr == arr); // true
2.2 不等运算符(!=) #
宽松不等,会进行类型转换:
typescript
console.log(1 != 2); // true
console.log(1 != "1"); // false (类型转换后相等)
console.log(0 != false); // false
console.log(null != undefined); // false
2.3 严格相等运算符(===) #
严格相等,不进行类型转换:
typescript
console.log(1 === 1); // true
console.log(1 === "1"); // false (类型不同)
console.log(0 === false); // false
console.log("" === false); // false
console.log(null === undefined); // false
// NaN的特殊情况
console.log(NaN === NaN); // false
console.log(Number.isNaN(NaN)); // true
2.4 严格不等运算符(!==) #
严格不等,不进行类型转换:
typescript
console.log(1 !== 2); // true
console.log(1 !== "1"); // true (类型不同)
console.log(0 !== false); // true
console.log(null !== undefined); // true
2.5 相等比较规则 #
| 表达式 | == 结果 | === 结果 |
|---|---|---|
| 1 == “1” | true | false |
| 0 == false | true | false |
| “” == false | true | false |
| null == undefined | true | false |
| [] == false | true | false |
| NaN == NaN | false | false |
三、关系比较 #
3.1 大于运算符(>) #
typescript
console.log(10 > 5); // true
console.log(5 > 10); // false
console.log(5 > 5); // false
// 字符串比较(字典序)
console.log("b" > "a"); // true
console.log("abc" > "abd"); // false
// 数字与字符串
console.log(10 > "5"); // true (字符串转为数字)
console.log("10" > 5); // true
3.2 小于运算符(<) #
typescript
console.log(5 < 10); // true
console.log(10 < 5); // false
console.log(5 < 5); // false
// 字符串比较
console.log("a" < "b"); // true
console.log("abc" < "abd"); // true
3.3 大于等于运算符(>=) #
typescript
console.log(10 >= 5); // true
console.log(5 >= 5); // true
console.log(5 >= 10); // false
// 字符串比较
console.log("b" >= "a"); // true
console.log("a" >= "a"); // true
3.4 小于等于运算符(<=) #
typescript
console.log(5 <= 10); // true
console.log(5 <= 5); // true
console.log(10 <= 5); // false
// 字符串比较
console.log("a" <= "b"); // true
console.log("a" <= "a"); // true
四、字符串比较 #
4.1 字典序比较 #
typescript
// 按Unicode码点比较
console.log("a" < "b"); // true
console.log("A" < "a"); // true (大写字母码点更小)
console.log("abc" < "abd"); // true
// 多字符比较
console.log("apple" < "banana"); // true
console.log("10" < "9"); // false (字符串比较,"1" < "9")
4.2 localeCompare方法 #
typescript
// 本地化字符串比较
console.log("a".localeCompare("b")); // -1
console.log("b".localeCompare("a")); // 1
console.log("a".localeCompare("a")); // 0
// 中文排序
const words = ["香蕉", "苹果", "橙子"];
words.sort((a, b) => a.localeCompare(b, "zh-CN"));
console.log(words); // ["橙子", "苹果", "香蕉"]
4.3 字符串排序 #
typescript
const fruits = ["banana", "apple", "cherry"];
// 默认排序(区分大小写)
fruits.sort();
console.log(fruits); // ["apple", "banana", "cherry"]
// 不区分大小写排序
const names = ["Alice", "bob", "Charlie"];
names.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
console.log(names); // ["Alice", "bob", "Charlie"]
五、对象比较 #
5.1 引用比较 #
typescript
const obj1 = { name: "Alice" };
const obj2 = { name: "Alice" };
const obj3 = obj1;
console.log(obj1 == obj2); // false (不同引用)
console.log(obj1 === obj2); // false
console.log(obj1 === obj3); // true (相同引用)
5.2 深度比较 #
typescript
function deepEqual(a: unknown, b: unknown): boolean {
if (a === b) return true;
if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) {
return false;
}
const keysA = Object.keys(a as object);
const keysB = Object.keys(b as object);
if (keysA.length !== keysB.length) return false;
for (const key of keysA) {
if (!keysB.includes(key)) return false;
if (!deepEqual((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])) {
return false;
}
}
return true;
}
const obj1 = { name: "Alice", age: 25 };
const obj2 = { name: "Alice", age: 25 };
const obj3 = { name: "Bob", age: 30 };
console.log(deepEqual(obj1, obj2)); // true
console.log(deepEqual(obj1, obj3)); // false
5.3 浅比较 #
typescript
function shallowEqual(a: object, b: object): boolean {
const keysA = Object.keys(a);
const keysB = Object.keys(b);
if (keysA.length !== keysB.length) return false;
for (const key of keysA) {
if ((a as Record<string, unknown>)[key] !== (b as Record<string, unknown>)[key]) {
return false;
}
}
return true;
}
const obj1 = { name: "Alice", age: 25 };
const obj2 = { name: "Alice", age: 25 };
const obj3 = { name: "Alice", age: 25, city: "Beijing" };
console.log(shallowEqual(obj1, obj2)); // true
console.log(shallowEqual(obj1, obj3)); // false
六、数组比较 #
6.1 引用比较 #
typescript
const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];
const arr3 = arr1;
console.log(arr1 == arr2); // false
console.log(arr1 === arr2); // false
console.log(arr1 === arr3); // true
6.2 内容比较 #
typescript
function arraysEqual(a: unknown[], b: unknown[]): boolean {
if (a.length !== b.length) return false;
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i]) return false;
}
return true;
}
const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];
const arr3 = [1, 2, 4];
console.log(arraysEqual(arr1, arr2)); // true
console.log(arraysEqual(arr1, arr3)); // false
6.3 JSON比较 #
typescript
function jsonEqual(a: unknown, b: unknown): boolean {
return JSON.stringify(a) === JSON.stringify(b);
}
const obj1 = { a: 1, b: 2 };
const obj2 = { a: 1, b: 2 };
const obj3 = { b: 2, a: 1 }; // 属性顺序不同
console.log(jsonEqual(obj1, obj2)); // true
console.log(jsonEqual(obj1, obj3)); // false (属性顺序不同)
七、特殊值比较 #
7.1 NaN比较 #
typescript
console.log(NaN === NaN); // false
console.log(NaN == NaN); // false
console.log(NaN !== NaN); // true
// 检查NaN的正确方法
console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN("hello")); // false
console.log(isNaN("hello")); // true (会先转换)
7.2 null和undefined比较 #
typescript
console.log(null === null); // true
console.log(undefined === undefined); // true
console.log(null == undefined); // true
console.log(null === undefined); // false
console.log(null == 0); // false
console.log(null > 0); // false
console.log(null >= 0); // true (特殊规则)
console.log(undefined == 0); // false
console.log(undefined > 0); // false
console.log(undefined < 0); // false
7.3 Infinity比较 #
typescript
console.log(Infinity === Infinity); // true
console.log(-Infinity === -Infinity); // true
console.log(Infinity === -Infinity); // false
console.log(Infinity > 1000000); // true
console.log(-Infinity < -1000000); // true
八、比较函数 #
8.1 排序比较函数 #
typescript
const numbers = [3, 1, 4, 1, 5, 9, 2, 6];
// 升序排序
numbers.sort((a, b) => a - b);
console.log(numbers); // [1, 1, 2, 3, 4, 5, 6, 9]
// 降序排序
numbers.sort((a, b) => b - a);
console.log(numbers); // [9, 6, 5, 4, 3, 2, 1, 1]
8.2 对象数组排序 #
typescript
interface User {
name: string;
age: number;
}
const users: User[] = [
{ name: "Alice", age: 25 },
{ name: "Bob", age: 30 },
{ name: "Charlie", age: 20 }
];
// 按年龄排序
users.sort((a, b) => a.age - b.age);
console.log(users);
// [{ name: "Charlie", age: 20 }, { name: "Alice", age: 25 }, { name: "Bob", age: 30 }]
// 按名称排序
users.sort((a, b) => a.name.localeCompare(b.name));
console.log(users);
// [{ name: "Alice", age: 25 }, { name: "Bob", age: 30 }, { name: "Charlie", age: 20 }]
九、最佳实践 #
9.1 使用严格相等 #
typescript
// 推荐
if (value === null) { }
if (value === undefined) { }
if (value === 0) { }
// 不推荐
if (value == null) { }
if (value == undefined) { }
9.2 检查null和undefined #
typescript
// 检查是否为null或undefined
if (value == null) {
// 等同于 value === null || value === undefined
}
// 或更明确
if (value === null || value === undefined) { }
// 使用空值合并
const result = value ?? "default";
9.3 类型安全的比较 #
typescript
function compare(a: number, b: number): number {
if (a < b) return -1;
if (a > b) return 1;
return 0;
}
console.log(compare(1, 2)); // -1
console.log(compare(2, 1)); // 1
console.log(compare(1, 1)); // 0
十、总结 #
本章学习了:
- 相等(==)和严格相等(===)
- 不等(!=)和严格不等(!==)
- 关系运算符(>、<、>=、<=)
- 字符串比较
- 对象和数组比较
- 特殊值比较(NaN、null、undefined、Infinity)
- 比较函数的使用
- 最佳实践
下一章,我们将学习逻辑运算符。
最后更新:2026-03-28