【发布时间】:2011-10-02 05:00:57
【问题描述】:
我是 JavaScript 新手,我正在尝试从 Internet 资源中学习它。虽然我知道会有大量 cr*p 材料,但大多数人似乎同意的一件事是 JS 中事物的真实性(举个例子去here)
现在我在实验中发现了这个奇怪的东西:
(true == 2) 是 false。为什么?
据我所知,2 是一个非零数字,所以它应该被评估为true。
【问题讨论】:
标签: javascript string boolean
我是 JavaScript 新手,我正在尝试从 Internet 资源中学习它。虽然我知道会有大量 cr*p 材料,但大多数人似乎同意的一件事是 JS 中事物的真实性(举个例子去here)
现在我在实验中发现了这个奇怪的东西:
(true == 2) 是 false。为什么?
据我所知,2 是一个非零数字,所以它应该被评估为true。
【问题讨论】:
标签: javascript string boolean
这是因为当相等运算符的任何一个操作数是数字时,几乎在所有情况下,另一个操作数都会转换为数字,然后比较结果。所以你最终将1(从true转换为2,而不是true与true进行比较。该规则的唯一例外是null、undefined,以及其默认值(参见下面的题外话)为null 或undefined 的对象;将数字与返回的false 进行比较(即使Number(null) 是0;不要问)。
the specification 的详细信息,第 11.9.3 节:“抽象等式比较算法”。这是 ES 5.1 中该部分的文本,但该链接指向当前编辑的草稿(这是每年的快照规范所基于的),并且有几个:
比较 x == y,其中 x 和 y 是值,产生 true 或 假。这样的比较是这样进行的:
- 如果Type(x) 与Type(y) 相同,则
- 返回执行Strict Equality Comparisonx === y的结果。
- 如果 x 为 null 且 y 为 undefined,则返回 true。
- 如果 x 为 undefined 且 y 为 null,则返回 true。
注意:此步骤在B.3.7.2 部分中替换。- 如果Type(x)是Number,Type(y)是String,返回比较结果x ==! ToNumber(y).
- 如果Type(x)是String,Type(y)是Number,返回比较结果! ToNumber(x) == y。
- 如果Type(x) 是BigInt 并且Type(y) 是字符串,那么
- 让n成为! StringToBigInt(y).
- 如果 n 为 NaN,则返回 false。
- 返回比较结果x == n。
- 如果Type(x)是String,Type(y)是BigInt,返回比较结果y == x.
- 如果Type(x) 是布尔值,返回比较结果! ToNumber(x) == y。
- 如果Type(y) 为布尔值,则返回比较结果x == ! ToNumber(y)。
- 如果Type(x) 是String、Number、BigInt 或Symbol 并且Type(y) 是Object,则返回比较结果x == ? ToPrimitive(y).
- 如果 Type(x) 是 Object 并且 Type(y) 是 String、Number、BigInt 或 Symbol,则返回比较结果? ToPrimitive(x) == y。
- 如果 Type(x) 是 BigInt 并且 Type(y) 是 Number,或者如果 Type(x ) 是数字,Type(y) 是 BigInt,则
- 返回 false。
注意:上面的!s 不是否定,它们表示下面的抽象操作永远不会导致突然完成。详情见this article about reading the spec。
如果您想检查它们是真还是假,您可以使用 bang (!) 或 double-bang (!!) 成语将它们强制转换为布尔值:
var a = true,
b = 2;
alert(a == b); // "false", 1 !== 2
alert(!!a == !!b); // "true", true === true
alert(!a == !b); // "true", false === false
a = false;
b = 0;
alert(a == b); // "true", 0 === 0
alert(!!a == !!b); // "true", false === false
alert(!a == !b); // "true", true === true
...但通常将== 或!= 与布尔值一起使用并不理想。但它确实出现了。
我倾向于使用双键,但在 JavaScript 中没有理由过度使用双键。 (在其他一些语言中,有一个论点是双键优于单键,尽管它与 if (!!x) 的一致性有关。在 JavaScript 中,您永远不需要在 if (x) 情况下使用双键,所以...)
(题外话:大多数 JavaScript 对象的默认值是一个字符串,尽管如果你将它转换为一个数字,通常像 "[object Object]" 最终是 NaN;但是构造函数可以覆盖它valueOf 和 toString 的行为。宿主对象的默认值取决于宿主环境。)
【讨论】:
使用非严格比较 (==) 如果操作数不是同一类型,它们将被强制转换和严格比较,如果操作数是数字或布尔值,则优先选择数字 (@987654321 @)。
所以true == 2 的计算结果为Number(true) === 2,即1 === 2,这是错误的。
当然,你总是可以强制比较你想要的东西,这是明确的,可以解决以后难以发现的问题:
true === Boolean(2) 为真。
【讨论】:
布尔值true 常量被提升为一个数字,即 1。
【讨论】: