相等(==)
相等运算符(==
)检查其两个操作数是否相等,返回一个布尔值结果。与严格相等运算符(===
)不同,它会比较不同类型的操作数,并尝试强制类型转换。
尝试一下
语法
x == y
描述
相等运算符(==
和 !=
)提供非严格相等语义。这可以大致总结如下:
- 如果操作数具有相同的类型,则按如下方式进行比较:
- 对象(Object):仅当两个操作数引用同一个对象时返回
true
。 - 字符串(String):只有当两个操作数具有相同的字符且顺序相同时才返回
true
。 - 数值(Number):如果两个操作数的值相同,则返回
true
。+0
和-0
被视为相同的值。如果任何一个操作数是NaN
,返回false
;所以,NaN
永远不等于NaN
。 - 布尔值(Boolean):仅当操作数都为
true
或都为false
时返回true
。 - 大整形(BigInt):仅当两个操作数值相同时返回
true
。 - 符号(Symbol):仅当两个操作数引用相同的符号时返回
true
。
- 对象(Object):仅当两个操作数引用同一个对象时返回
- 如果其中一个操作数为
null
或undefined
,另一个操作数也必须为null
或undefined
以返回true
。否则返回false
。 - 如果其中一个操作数是对象,另一个是基本类型,按此顺序使用对象的
@@toPrimitive()
(以"default"
作为提示),valueOf()
和toString()
方法将对象转换为基本类型。(这个基本类型转换与相加中使用的转换相同。) - 在这一步,两个操作数都被转换为基本类型(String、Number、Boolean、Symbol 和 BigInt 中的一个)。其余的转换是逐个进行的。
- 如果是相同的类型,使用步骤 1 进行比较。
- 如果其中一个操作数是 Symbol 而另一个不是,返回
false
。 - 如果其中一个操作数是布尔型而另一个不是,则将布尔型转换为数字:
true
转换为 1,false
转换为 0。然后再次松散地比较两个操作数。 - Number to String:使用与
Number()
构造函数相同的算法将字符串转换为数字。转换失败将导致NaN
,这将保证相等是false
。 - Number to BigInt:按数值进行比较。如果数值为 ±∞ 或
NaN
,返回false
。 - String to BigInt:使用与
BigInt()
构造函数相同的算法将字符串转换为 BigInt。如果转换失败,返回false
。
宽松相等是对称的:A == B
对于 A
和 B
的任何值总是具有与 B == A
相同的语义(应用转换的顺序除外)。
该运算符与严格相等(===
)运算符之间最显著的区别是,严格相等运算符不尝试类型转换。相反,严格相等运算符总是认为不同类型的操作数是不同的。严格相等运算符本质上只执行第 1 步,然后对所有其他情况返回 false
。
上面的算法有一个“故意违反”:如果其中一个操作数是 document.all
,则它被视为 undefined
。这意味着 document.all == null
是 true
,但 document.all === undefined && document.all === null
是 false
。
示例
没有类型转换的比较
1 == 1; // true
"hello" == "hello"; // true
有类型转换的比较
"1" == 1; // true
1 == "1"; // true
0 == false; // true
0 == null; // false
0 == undefined; // false
0 == !!null; // true, 看看逻辑非运算符
0 == !!undefined; // true, 看看逻辑非运算符
null == undefined; // true
const number1 = new Number(3);
const number2 = new Number(3);
number1 == 3; // true
number1 == number2; // false
比较对象
const object1 = {
key: "value",
};
const object2 = {
key: "value",
};
console.log(object1 == object2); // false
console.log(object1 == object1); // true
比较字符串和 String 对象
请注意,使用构造的字符串 new String()
是对象。如果将其中之一与字符串文字进行比较,则该 String
对象将被转换为字符串文字并对其内容进行比较。但是,如果两个操作数都是 String
对象,则将它们作为对象进行比较,并且必须引用相同的对象才能进行比较:
const string1 = "hello";
const string2 = String("hello");
const string3 = new String("hello");
const string4 = new String("hello");
console.log(string1 == string2); // true
console.log(string1 == string3); // true
console.log(string2 == string3); // true
console.log(string3 == string4); // false
console.log(string4 == string4); // true
比较日期和字符串
const d = new Date("December 17, 1995 03:24:00");
const s = d.toString(); // for example: "Sun Dec 17 1995 03:24:00 GMT-0800 (Pacific Standard Time)"
console.log(d == s); //true
比较数组和字符串
const a = [1, 2, 3];
const b = "1,2,3";
a == b; // true, `a` converts to string
const c = [true, 0.5, "hey"];
const d = c.toString(); // "true,0.5,hey"
c == d; // true
规范
Specification |
---|
ECMAScript Language Specification # sec-equality-operators |
浏览器兼容性
BCD tables only load in the browser