为啥 NaN = !NaN 返回真?

Posted

技术标签:

【中文标题】为啥 NaN = !NaN 返回真?【英文标题】:Why does NaN = !NaN return true?为什么 NaN = !NaN 返回真? 【发布时间】:2017-05-10 01:38:53 【问题描述】:

NaN 是那些起源有问题的残余实现之一,但在大多数情况下 我明白了。但是,我今天在 Node 提示符中输入了这个,并不能真正理解它......

NaN = !NaN
> true

这只是返回!NaN 的评估结果吗?这是有道理的,但我很惊讶尝试将 NaN 分配给另一个值时没有错误。

注意:这个问题是关于这个特定的语法结构;有很多与 NaN 和 isNaN 相关的问题,但我在谷歌搜索后找不到答案。感谢 Ori Drori 的best answer thus far。

console.log(NaN = !NaN);

【问题讨论】:

@pvg 看起来不像那个副本。这里没有 NaN 与任何东西的比较。 @pvg 我在发布之前进行了搜索,但没有看到我所问的具体问题的答案。 @MartinSmith 你是对的,我误读了这个问题,删除了标志。在相关答案的海洋中找出一个骗子要容易得多,但要困难得多。 【参考方案1】:

您将true 分配给NaN,而不是使用=====NaN!NaN 进行比较,因此该操作返回分配的值-> truejavascript 会默默地忽略这个赋值,因为 NaN is read only。

console.log(NaN = true);

// NaN hasn't changed
console.log(NaN);

如果你将use strict 添加到你的代码中,JS 会抛出一个read only 错误:

'use strict';
NaN = true;

【讨论】:

很好的答案,谢谢!我应该使用严格模式的更多理由。 严格模式规则:)【参考方案2】:

尝试在 strict 模式下运行 Javascript 以避免大部分问题。

NaN、null、false、""、null、undefined、0 等它们在 javascript 中被视为虚假值(请记住 falsy !== false),无论您是否使用 strict 模式.

// 'use strict';

console.log(!NaN);       // true
console.log(!null);      // true
console.log(!false);     // true
console.log(!"");        // true
console.log(!null);      // true
console.log(!undefined); // true
console.log(!0);         // true

在 Python 中也是如此,但 NaN 除外。例如,

print(not False)        # True
print(not None)         # True
print(not float("NaN")) # False
print(not "")           # True
print(not 0)            # True

混乱的来源 当我们使用多种语言时,有时可能会造成混淆。

例如,

在 Python 中,'cat' in ['fat', 'cat', 'rat', 'hat'] 返回 True。

在 Javascript 中,'cat' in ['fat', 'cat', 'rat', 'hat'](完全相同的代码)无论您是否使用 strict 模式都会返回 false。

在 Python 中,print(not []) 返回 True。

在 Javascript 中 console.log(![]); 返回 false。

这就是我总是喜欢使用调试器、REPL 等的原因之一,无论代码多么简单。

【讨论】:

【参考方案3】:

Javascript 真的很奇怪:当你写的时候

NaN = true  // true

你基本上在你的陈述中做了,你得到“真实”。这与您编写时的行为相同

a = true  // true

返回赋值右侧的位置。但是如果你添加var并写

var a = true  // undefined

然后什么都不返回。此外,如果您将 NaN 替换为计算结果为 NaN 的表达式,例如

1/"a" = true  // error!

然后你会得到一个 ReferenceError。我建议永远不要使用分配的返回值。该行为尚无定论,您的代码将难以阅读。您可以启用“严格模式”来为您检查。

【讨论】:

不错!谢谢你的澄清!【参考方案4】:

使用= 运算符,您可以将值分配给变量。但是,您不知道的是,通过这样做,它会返回所分配的值。打字:

v = 1

在 JavaScript REPL 中将显示 1,因为这是分配给 v 的内容。所以,做:

NaN = !NaN

NaN 的相反值分配给NaN 本身。由于布尔值中的NaNfalse,那么布尔值中的!NaN 必须是true

【讨论】:

【参考方案5】:

= 是赋值运算符。 ===== 是比较运算符。

NaN == !NaN
false
NaN === !NaN
false

也许更令人惊讶:

NaN  == NaN
false
NaN  === NaN
false

有关 NaN 的更多信息:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/NaN

【讨论】:

以上是关于为啥 NaN = !NaN 返回真?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 [NaN].includes(NaN) 在 JavaScript 中返回 true?

为啥 Double.NaN==Double.NaN 返回 false?

js时间操作getTime(),IOS小程序真机上返回显示NAN

为啥 typeof NaN 返回“数字”?

为啥这个函数返回 NaN?

为啥 Math.round() 为 NaN 参数返回 0?