首页 > 代码库 > 同样在JavaScript中

同样在JavaScript中

ES6有三个内置决定一些设施x和一些y是“相同的”。 它们是:平等或“双等于”(==),严格平等或平等“三重”(===),Object.is。 (注意,Object.is在ES6补充道。 等于两倍和三倍等于存在ES6之前,和他们的行为没有改变。)

概述

演示,下面是三个同样使用的比较:

x = = y
 
x = = = y
 
Object(x, y)
 

短暂、双等于将执行类型转换当比较两件事;三等于将做同样的比较没有类型转换(通过简单总是返回false如果不同类型);Object.is行为一样等于三倍,但与特殊处理NaN-0+0据说,最后两个不相同的,Object.is(NaN, NaN)true。 (比较NaNNaNordinarily-i.e。 ,使用等于两倍或三倍equals-evaluatesfalse,因为IEEE 754这么说)。

注意区分这些都有与原语的处理;他们比较参数是否在概念上类似的结构。 对于任何销售对象xy具有相同的结构,但不同的对象本身,所有上述形式将评估false

例如:

让 x = { value: 17 };让 y = { value: 17 };console日志(Object(x, y));/ /错误;console日志(x = = = y);        / /错误console日志(x = = y);         / /错误
 

抽象的平等,严格的平等,和相同的值

由ES5的比较==描述的是算法部分11.9.3、抽象的平等。 的===比较是11.9.6、严格平等算法。 (去看看这些。 他们短暂的和可读的。 提示:先读严格平等算法)。 ES5还描述了,9.12节,SameValue算法JS引擎内部使用。 它很大程度上是一样的严格平等算法,除了11.9.6.4和9.12.4不同处理Number年代。ES6仅仅提出公开该算法通过Object.is

与平等的两倍和三倍,我们可以看到,除了在11.9.6.1前期做类型检查,严格平等算法抽象平等的一个子集算法,因为11.9.6.2-7对应11.9.3.1.a-f。

模型为理解平等比较?

ES6之前,你可能会说等于两倍和三倍等于,一个是“增强”的其他版本。 比如,有人可能会说,双等于是三重的扩展版本等于,因为前者后者所做的每一件事情,但在其操作数类型转换。 例如,6 == "6"。 (或者,有人可能会说,双等于基线,和三倍等于一个增强版本,因为它需要两个操作数是相同的类型,因此它添加了一个额外的约束。 哪一个是更好的模型来理解取决于你如何看待事情。)

然而,这种思维方式对内置的相同运营商不是一个模型,可以延伸到允许ES6的地方Object.is在这个“谱”。Object.is不是简单的“宽松”要比双等于或比三等于“严格”,也不适合介于两者之间(即。 ,既严格等于两倍多,但比三等于宽松)。 我们可以看到下面从千篇一律的比较表,这是由于Object.is处理NaN。 注意,如果Object.is(NaN, NaN)评估,false,我们可能说它适合宽松/严格光谱作为一个甚至更严格的三重平等形式,区分-0+0。 的NaN然而,处理意味着这是不真实的。 不幸的是,Object.is仅仅是想到的特定的特征,而不是其松动或严格相等运算符。

千篇一律的比较
xy=====Object.is
undefinedundefinedtruetruetrue
nullnulltruetruetrue
truetruetruetruetrue
falsefalsetruetruetrue
"foo""foo"truetruetrue
{ foo: "bar" }xtruetruetrue
00truetruetrue
+0-0truetruefalse
0falsetruefalsefalse
""falsetruefalsefalse
""0truefalsefalse
"0"0truefalsefalse
"17"17truefalsefalse
[1,2]"1,2"truefalsefalse
new String("foo")"foo"truefalsefalse
nullundefinedtruefalsefalse
nullfalsefalsefalsefalse
undefinedfalsefalsefalsefalse
{ foo: "bar" }{ foo: "bar" }falsefalsefalse
new String("foo")new String("foo")falsefalsefalse
0nullfalsefalsefalse
0NaNfalsefalsefalse
"foo"NaNfalsefalsefalse
NaNNaNfalsefalsetrue

什么时候使用Object.is与三等于

除了对待的方式NaN一般来说,只有时间Object.is对零的特殊行为可能是感兴趣的在追求某些元编程方案,特别是关于属性描述符当你的工作是最理想的镜子的一些特点Object.defineProperty。 如果你的用例不需要这个,建议避免Object.is和使用===来代替。 即使你的需求涉及到比较两个NaN值评估true代价,通常更容易处理NaN检查(使用isNaN方法可以从以前版本的ECMAScript)比如何计算可能会影响周围的标志任何零你遇到的比较。

这里有一个不彻底的内置方法列表和运营商,可能导致之间的区别-0+0体现在你的代码:

- (unary negation)

很明显,否定0生产-0。 但表达的抽象可以引起-0当你没有意识到它的蠕变。 例如,考虑:

让 stoppingForce = obj。mass * - - - - - -obj。velocity
 

如果obj.velocity0(或计算0),一个-0介绍了在那个地方,传播到吗stoppingForce

Math.atan2
Math.ceil
Math.pow
Math.round
它是可能的-0是引入一个表达式的返回值这些方法在某些情况下,即使没有-0存在的参数。 如。 ,使用Math.pow提高-无限任何负面的力量,奇怪的指数评估-0。 指个人的文档的方法。
Math.floor
Math.max
Math.min
Math.sin
Math.sqrt
Math.tan
可以得到一个-0返回值的这些方法在某些情况下-0存在的参数。 例如,Math.min(-0, +0)评定,-0。 指个人的文档的方法。
~
< <
> >
这些运营商内部使用ToInt32算法。 由于只有一个为0表示内部32位整数类型,-0不会生存往返后逆操作。 如。 ,两个Object.is(~~(-0), -0)Object.is(-0 << 2 >> 2, -0)评估,false

依靠Object.is当零的signedness不考虑危险。 当然,当目的是区分-0+0,它到底是什么。

同样在JavaScript中