首页 > 代码库 > 同样在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
。 (比较NaN
与NaN
ordinarily-i.e。 ,使用等于两倍或三倍equals-evaluatesfalse
,因为IEEE 754这么说)。
注意区分这些都有与原语的处理;他们比较参数是否在概念上类似的结构。 对于任何销售对象x和y具有相同的结构,但不同的对象本身,所有上述形式将评估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
仅仅是想到的特定的特征,而不是其松动或严格相等运算符。
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 |
什么时候使用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.velocity
是0
(或计算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中