JS比较相等的方式

"===" 严格相等操作符

a===b比较规则如下:

  1. 如果a与b类型不同,则不相等,返回false
  2. 如果a=null且b==null,则相等,返回true
  3. 如果a=undefined且b=undefined,则相等,返回true
  4. 如果a与b都是布尔值true或都是布尔值false,则相等,返回true
  5. 如果a与b都是数值且相等,则相等,返回true。(===认为0与-0相等
  6. 如果a和b都为Infinity,则相等,返回true(Infinity与-Infinity不相等,NaN与包括NaN的任何数都不严格相等
  7. 如果a,b都是字符串,且相同位置的16为Unicode码值完全相同,则a与b相等,返回true。(如果a与b长度不同,或者它们看起来相同,但是Unicode值不同,则不相等)
  8. 如果a,b引用同一个对象(数组、函数),则相等,返回false。(如果它们引用不同对象,即使它们拥有完全相同的属性和属性值,也不相等

"=="相等操作符

“==“在比较两个数据时,如果两个数据类型相等,则会按照严格相等"==="来比较,如果比较的两个数据类型不同,进行按照以下规则尝试类型转换之后再判定相等关系:

  1. 如果一个值是null,另一个值是undefined,则相等。
  2. 如果一个值是数值,另一个是字符串,把字符串转换为数值,再比较转换后的数值。
  3. 如果一个是布尔值,将布尔值转为数值(true转换为1,false转换为0),再比较。
  4. 如果一个值是bigint(大整数),则将另一个值转成数值,再比较。
  5. 如果一个值是symbol(符号),只有另外一个值也引用与该值完全相同的符号才相等。
  6. 如果一个值是对象,另一个值为布尔值,将对象转为true,再比较。
  7. 如果一个值是对象(包含函数),另一个值为数值或字符串,将对象尝试隐式调用其valueOf方法,如果valueOf方法返回非对象数据类型,则使用这个返回值与另一个值进行比较,如果valueOf返回对象类型,则再尝试用其toString方法的返回值与另一个值比较。(对于Date类型,会先尝试toString,再尝试valueOf

转换规则如下表:

转换为字符串 转换为数值 转换为布尔值
undefined "undefined" NaN false
null "null" 0 false
true "true" 1
false "false" 0
""(空字符串) 0 false
“1.2”(非空数值字符串) 1.2 true
“abc”(非空非数值字符串) NaN true
0 "0" false
-0 "0" false
1(有限非0数值) "1" true
Infinity "Infinity" true
-Infinity "-Infinity" true
NaN "NaN" false
{}(任何对象) 上述第7条规则 上述第七条规则 true
[](空数组) “” 0 true
[2](一个数值元素) "2" 2 true
["a"] 调用join方法 NaN true
任何函数 上述规则7 NaN true

认真阅读下面这段代码与注释内容后你一定会有很多收获!当然这里并没有涵盖所有的数据比较的排列组合

console.log(1 == "1"); // true 将字符串"1"转成数值1
console.log(2 == true); // false 将true转成1
console.log("abc" == true); // false 将true转成字符串"true"
console.log(null == undefined); // true 规则1
console.log(NaN == "abc"); // 将"abc"转成数值为NaN,但==认为NaN与NaN不相等
console.log(Infinity == "Infinity"); // 将字符串"Infinity"转成数值Infinity
console.log(0 == -0); // ==认为+0与-0相等
console.log([] == ""); // true 空数组转成空字符串
console.log([] == true); // false []转成0.true转成1
console.log([] == []); // false 两个数组不是同一个对象
console.log([] == ![]); // false 后一个空数组转成布尔值取反为false,转换后类型不一样。false再转成0,再将前一个数组转成数值0
console.log([1] == 1); // true 数组转[1]调用join方法转成字符串"1",再将字符串"1"转成数值1
console.log([1, 2] == "1,2"); // true 数组调用join方法转成字符串"1,2"
console.log(Symbol.iterator == false); // false 规则5
console.log(Symbol.iterator == true); // false 规则5
console.log(2n == "2"); // true 把字符串"2"转成数值2,再与bigint值2n 进行值的比较
let o1 = {
  valueOf() {
    return 3;
  },
};

let o2 = {
  valueOf() {
    return {};
  },
  toString() {
    return "3";
  },
};

console.log(o1 == o2); // false 不是同一个对象
console.log(o1 == 3); // true 按照规则7将o1转换为数值3
console.log(o2 == 3); // true 按照规则7将o2转换为"3"(先调用valueOf返回不是非对象数据类型,会再调用toString),再将"3"转换为数值3

Object.is(a,b)判断a,b是否为同一个值(SameValue)

Object.is方法判断两个值是否为同一个值,如果满足以下任意条件则两个值相等:

  • 都是 undefined
  • 都是 null
  • 都是 true 或都是 false
  • 都是相同长度、相同字符、按相同顺序排列的字符串
  • 都是相同对象(意味着都是同一个对象的值引用)
  • 都是数字且
    • 都是 +0
    • 都是 -0
    • 都是 NaN
    • 都是同一个值,非零且都不是 NaN

Object.is() 与 == 不同。== 运算符在判断相等前对两边的变量(如果它们不是同一类型)进行强制转换(这种行为将 "" == false 判断为 true),而 Object.is 不会强制转换两边的值。

Object.is() 与 === 也不相同。差别是它们对待有符号的零和 NaN 不同,例如,=== 运算符(也包括 == 运算符)将数字 -0 和 +0 视为相等,而将Number.NaN与NaN 视为不相等。

SameValueZero(api暂未提供)

认为0,+0,-0都是相等的。其他的与SameValue一样。

数组的includes方法,Map的has等方法内部的比较就是这种规则。

猜你喜欢

转载自blog.csdn.net/m0_52726759/article/details/129393535