Object.is vs ===


141

我偶然发现了使用此比较的代码示例:

var someVar = 0;
Object.is(false, someVar); //Returns false 

我知道false == 0会是true这就是为什么我们有===

如何Object.is不同===

Answers:


174

===在JavaScript中被称为严格比较运算符。Object.is和严格的比较运算符的行为完全一样,除了NaN+0/-0

从MDN:

Object.is()方法不同于等于===运算符的相等方法。的===操作者(和==操作员以及)对待数值-0和0为相等和治疗Number.NaN为不等于NaN

以下代码突出显示了===和之间的区别Object.is()

console.log(+0 === -0); //true
console.log(Object.is(+0, -0)); //false

console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); //true

console.log(Number.NaN === Number.NaN); // false
console.log(Object.is(Number.NaN, Number.NaN)); // true

console.log(NaN === Number.NaN); // false
console.log(Object.is(NaN, Number.NaN)); // true

在此处输入图片说明

您可以在此处找到更多示例。

注意Object.is是ECMAScript 6提案的一部分,尚未得到广泛支持(例如,任何版本的Internet Explorer或许多其他浏览器的较早版本均不支持它)。但是,您可以将polyfill用于非ES6浏览器,可以在上面给出的链接中找到。


26
答案的第一行应该是“除了NaN以及+0和-0以外,它们的行为完全相同”。
本杰明·格林鲍姆

1
@BenjaminGruenbaum好建议。使答案更易于阅读。干杯。
Gurpreet Singh

3
@ humble.rumble对此进行了详尽的讨论-静态方法更简单-它们没有上下文问题或原始问题。例如,在您的示例中,我期望false,但是JS的新手会期望true,因为.x在字符串上将其放入String对象(而不是字符串原始值)中,并且比较将在对象和字符串之间进行-这非常微妙的陷阱-静态避免了这些问题,静态方法更简单易用。
本杰明·格林鲍姆

2
@ humble.rumble为了比较DOM节点,已经有这样一种方法,请参见isEqualNode。范例:document.createElement('div').isEqualNode(document.createElement('div')) === true
Rob W

2
2017更新:Object.is()现在在所有主要浏览器中得到广泛支持。
Sterling Bourne

56

Object.is使用规范的SameValue算法,而===使用严格相等算法。关于严格平等算法的注释指出了区别:

该算法不同于SameValue算法...在处理带符号的零和NaN方面。

注意:

  • NaN === NaN是错误的,但是Object.is(NaN, NaN)真实的
  • +0 === -0是真的,但是Object.is(+0, -0)错误的
  • -0 === +0是真的,但是Object.is(-0, +0)错误的

JavaScript 至少具有四种“平等”:

  • “松散”(==),将强制操作数尝试使其匹配。规则已明确规定,但并非显而易见。("" == 0true; "true" == truefalse,...)。
  • “严格”(===),其中不同类型的操作数将不会被强制转换(并且将不相等),但是请参见上面的注释NaN以及正零和负零。
  • SameValue-如上所述(由所使用Object.is)。
  • SameValueZero-与SameValueexcept 类似+0-0并且相同,而不是不同(用于Map键和Array.prototype.includes)。

还存在对象对等,这不是语言或运行时本身提供的,而是通常表示为:对象具有相同的原型,相同的属性,并且它们的属性值相同(通过合理的“相同”定义) )。


SameValue算法

  • 如果Type(x)与Type(y)不同,则返回false。
  • 如果Type(x)是Number,则
    • 如果x为NaN而y为NaN,则返回true。
    • 如果x为+ 0,y为-0,则返回false。
    • 如果x为-0,y为+0,则返回false。
    • 如果x与y相同,则返回true。
    • 返回false。
  • 返回SameValueNonNumber(x,y)。

...其中SameValueNonNumber为:

  • 断言:Type(x)不是Number。
  • 断言:Type(x)与Type(y)相同。
  • 如果Type(x)为Undefined,则返回true。
  • 如果Type(x)为Null,则返回true。
  • 如果Type(x)为String,则
    • 如果x和y是完全相同的代码单元序列(在相同的索引处具有相同的长度和相同的代码单元),则返回true;否则,返回true。否则,返回false。
  • 如果Type(x)为布尔值,则
    • 如果x和y均为true或均为false,则返回true;否则,返回true。否则,返回false。
  • 如果Type(x)是Symbol,则
    • 如果x和y都是相同的Symbol值,则返回true;否则,返回true。否则,返回false。
  • 如果x和y是相同的Object值,则返回true。否则,返回false。

严格平等算法

  1. 如果Type(x)与Type(y)不同,则返回false。
  2. 如果Type(x)是Number,则
    • 如果x为NaN,则返回false。
    • 如果y为NaN,则返回false。
    • 如果x与y相同,则返回true。
    • 如果x为+ 0,y为-0,则返回true。
    • 如果x为-0,y为+0,则返回true。
    • 返回false。
  3. 返回SameValueNonNumber(x,y)。

2

Object.is = function(v1, v2){
  //test for `-0`
  if(v1 === 0 && v2 === 0) {
    return 1 / v1 === 1 / v2;
  }
  
  //test for `NaN`
  if(v1 !== v1) {
    return v2 !== v2;
  }
  
  //everything else
  return v1 === v2;
}

上面是polyfill函数Object.is,用于向有兴趣的人展示如何工作。对You-Don't-Know-JS的引用


2

摘要:

Object.is()函数将2个值作为参数,如果2个给定值完全相同,则返回true,否则将返回false。

我们为什么需要这个?

您可能会认为,我们已经可以使用===运算符在javascript中进行严格的相等(检查类型+值)检查,为什么我们需要此功能?严格的平等在某些情况下是不够的,它们是:

console.log(NaN === NaN);   // false
console.log(-0 === +0);     // true

Object.is() 通过比较这些值以查看它们是否相似来帮助我们,这是严格相等运算符无法做到的。

console.log(Object.is(NaN, NaN));  // true
console.log(Object.is(-0, 0));     // false
console.log(Object.is(+0, +0));    // true
console.log(Object.is(+0, -0));    // false


0

简而言之,它们是相似的,但是Object.is更智能,更准确。

让我们看看...

+0 === -0 //true

但这是不完全正确的,因为它忽略了-+之前...

现在我们使用:

Object.is(+0, -0) //false

如您所见,比较起来更准确。

同样,在这种情况下NaN,更像是正确的,可以认为NaN是相同的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.