ES2015中有四种相等算法:
- 抽象(非严格)相等比较 (==)
- 严格相等比较 (===):用于 Array.prototype.indexOf, Array.prototype.lastIndexOf, 和 case-matching
- 同值零: 用于 %TypedArray% 和 ArrayBuffer 构造函数、以及Map和Set操作, 并将用于 ES2016/ES7 中的String.prototype.includes
- 同值: 用于所有其他地方
JavaScript提供三种不同的值比较操作:
- 严格相等比较 (也被称作"strict equality", “identity”, “triple equals”),使用 === ,
- 抽象相等比较 (“loose equality”,“double equals”) ,使用 ==
- 以及 ES6的 Object.is()
这几种方法都能对值进行比较操作,如何使用它们取决于什么样的应用场景。
抽象相等和严格相等想必都比较了解了,那么就简单介绍下ES6的 Object.is()。
语法和参数
// value1 被比较的第一个值。
// value2 被比较的第二个值。
Object.is(value1, value2);
返回值
一个 Boolean 类型标示两个参数是否是同一个值
与 == 和 ===的区别
- +0 和 -0
- NaN
- == 和 === 会将数字 -0 和 +0 视为相等, NaN视为不等,而Object.is() 计算+0不等于-0,NaN等于自身
function useSameData() {
let notNumber1 = NaN
let notNumber2 = NaN
let positiveNumber = +0
let negativeNumber = -0
console.log(notNumber1 === notNumber2); // false
console.log(Object.is(notNumber1, notNumber2)); // true
console.log(notNumber1 === notNumber2); // true
console.log(Object.is(positiveNumber, negativeNumber)); // false
}
ES5 可以通过下面的代码,部署Object.is。
Object.defineProperty(Object, 'is', {
value: function(x, y) {
if (x === y) {
// 针对+0 不等于 -0的情况
return x !== 0 || 1 / x === 1 / y;
}
// 针对NaN的情况
return x !== x && y !== y;
},
configurable: true,
enumerable: false,
writable: true
});
如何去理解
有些人可能会认为双等是三等的扩展版,因为他处理三等所做的,还做了类型转换。另一些人可能会认为三等是双等的扩展,因为他不仅判断值还要求两个参数的类型相同,所以增加了更多的限制。然而Object.is 因为上述例子的关系,反而和它们没有太多关联。因为它既不比双等更宽松,也并不比三等更严格,当然也不是在他们中间。它是应该被认为是有其特殊的用途,而不应说他和其他的相等更宽松或严格。
何时使用
三等应该是存在于大多数朋友的日常代码中,因为它几乎满足了所有的要求。而Object.is 的特殊性,导致可能当你需要一些元编程方案时,它对待0的特殊方式,特别是关于属性描述器,即你的工作需要去镜像Object.defineProperty的一些特性时。如果你需要比较两个NaN使其结果为true,总的来说编写使用NaN 检查的特例函数(用旧版本ECMAScript的isNaN方法)也会比想出一些计算方法让Object.is不影响不同符号的0的比较更容易些。如果有区别对待-0和+0的编程时,可以在文档地址里查看具体的使用方法。
示例
Object.is('foo', 'foo'); // true
Object.is(window, window); // true
Object.is('foo', 'bar'); // false
Object.is([], []); // false
var foo = { a: 1 };
var bar = { a: 1 };
Object.is(foo, foo); // true
Object.is(foo, bar); // false
Object.is(null, null); // true
// 特例
Object.is(0, -0); // false
Object.is(0, +0); // true
Object.is(-0, -0); // true
Object.is(NaN, 0/0); // true
兼容性
大IE依旧对这类 api 有抗拒,要适配IE浏览器的朋友慎用
资料参考链接:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/is
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Equality_comparisons_and_sameness