• 认真地记录技术中遇到的坑!

JavaScript 中的相等性判断

JavaScript 悠悠 9个月前 (01-30) 239次浏览 0个评论

概述

ECMAScript 2015/ES6中有四种相等算法:

  • 抽象相等比较(==)
  • 严格相等比较(===) Array.prototype.indexOf, Array.prototype.lastIndexOf, 和 case-matching
  • 同值零: 用于 %TypedArray% 和 ArrayBuffer 构造函数、以及Map和Set操作, 并将用于 ES2016/ES7 中的String.prototype.includes
  • 同值: 用于所有其他地方

JavaScript提供三种不同的值比较操作:

  • 严格相等 (“triple equals” 或 “identity”),使用 ===
  • 宽松相等 (“double equals”) ,使用 ==
  • 以及 Object.is (ECMAScript 2015/ ES6 新特性)

说明如下:

  • == 双等号将执行类型转换
  • === 三等号不进行类型转换 (如果类型不同, 直接返回 false )
  • Object.is的行为方式与三等号相同,但是对于NaN、-0和+0进行特殊处理,所以最后两个不相同,而Object.is(NaN,NaN)将为 true
  • 使用双等号或三等号将NaN与NaN进行比较,结果为false
  • 对于任意两个不同的非原始对象,即便他们有相同的结构,以上三个运算符都会计算得到 false

更多详细内容可以参考官网文档

严格相等 ===

全等操作符比较两个值是否相等,两个被比较的值在比较前都不进行隐式转换,需要注意:

  • 如果两个被比较的值具有不同的类型,这两个值是不全等的
  • 如果两个被比较的值类型相同,值也相同,并且都不是 number 类型时,两个值全等
  • 如果两个值都是 number 类型,当两个都不是 NaN,并且数值相同,或是两个值分别为 +0 和 -0 时,两个值被认为是全等的
  • 全等操作符认为 NaN 与其他任何值都不全等,包括它自己(等式 (x !== x) 成立的唯一情况是 x 的值为 NaN)
  • 需要注意两个浮点数比较时的进度缺失问题: 0.1 + 0.2 === 0.3 为false
var num = 0;  // Number 原始类型
var obj = new String("0"); // String 对象
var str = "0";  // String 原始类型
var b = false;  // Boolean 原始类型

console.log(num === num); // true
console.log(obj === obj); // true
console.log(str === str); // true

console.log(num === obj); // false
console.log(num === str); // false
console.log(obj === str); // false
console.log(null === undefined); // false
console.log(obj === null); // false
console.log(obj === undefined); // false
console.log(0.1+0.2 === 0.3); //false

非严格相等 ==

相等操作符比较两个值是否相等,在比较前将两个被比较的值转换为相同类型。在转换后(等式的一边或两边都可能被转换),最终的比较方式等同于全等操作符 === 的比较方式。

  • 相等操作符满足交换律
  • 几乎所有的对象都与 undefined 和 null 不相等
  • 大部分浏览器允许 document.all 对象,在某些极端情况下,充当效仿 undefined 的角色,此时和undefined相等
  • 当一个对象和原始对象比较时,会尝试调用对象的valueOf()或者toString()方法将对象转换为原始值

相等操作符对于不同类型的值,进行的比较如下表所示:

  B
    Undefined Null Number String Boolean Object
A Undefined true true false false false IsFalsy(B)
Null true true false false false IsFalsy(B)
Number false false A === B A === ToNumber(B) A=== ToNumber(B) A=== ToPrimitive(B) 
String false false ToNumber(A) === B A === B ToNumber(A) === ToNumber(B) ToPrimitive(B) == A
Boolean false false ToNumber(A) === B ToNumber(A) === ToNumber(B) A === B ToNumber(A) == ToPrimitive(B)
Object false false ToPrimitive(A) == B ToPrimitive(A) == B ToPrimitive(A) == ToNumber(B) A === B

ToNumber(A) 尝试在比较前将参数 A 转换为数字,这与 +A(单目运算符+)的效果相同。

ToPrimitive(A)通过尝试依次调用 A 的A.toString() 和 A.valueOf() 方法,将参数 A 转换为原始值(Primitive)

var num = 0;
var obj = new String("0");
var str = "0";
var b = false;

console.log(num == num); // true
console.log(obj == obj); // true
console.log(str == str); // true

console.log(num == obj); // true
console.log(num == str); // true
console.log(obj == str); // true
console.log(null == undefined); // true

// both false, except in rare cases
console.log(obj == null);
console.log(obj == undefined);

Object.is

Object.is 算是JavaScript中同值零比较算法暴露出的一个方法。

Object.is基本和严格相等===相同,确定两个值是否在任何情况下功能上是相同的。

Object.is认为 +0 和 -0 不相等。

另外一种相等比较算法:同值算法认为 +0 和 -0 相等。

Object.is('foo', 'foo');     // true
Object.is(window, window);   // true

Object.is('foo', 'bar');     // false
Object.is([], []);           // false

var test = { a: 1 };
Object.is(test, test);       // true

Object.is(null, null);       // true

// Special Cases
Object.is(0, -0);            // false
Object.is(-0, -0);           // true
Object.is(NaN, 0/0);         // true

判等表

下面列出对于不同类型的比较,==,=== 以及 Object.is 的区别。

判等
x y == === Object.is
undefined undefined true true true
null null true true true
true true true true true
false false true true true
"foo" "foo" true true true
{ foo: "bar" } x true true true
0 0 true true true
+0 -0 true true false
0 false true false false
"" false true false false
"" 0 true false false
"0" 0 true false false
"17" 17 true false false
[1,2] "1,2" true false false
new String("foo") "foo" true false false
null undefined true false false
null false false false false
undefined false false false false
{ foo: "bar" } { foo: "bar" } false false false
new String("foo") new String("foo") false false false
0 null false false false
0 NaN false false false
"foo" NaN false false false
NaN NaN false false true

转载请注明出处 JavaScript 中的相等性判断
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址