在Javascript中,几乎所有表达式(所有表达式?)都具有“真实性”值。如果将表达式放在期望为 bool(boolean) 值的语句中,则它将等于 bool(boolean) 值。例如:

let a = 'foo'

if (a) {
  console.log('a is truthy!');
}
// Will print 'a is truthy!'.

在某些工作场所中,通常会通过两次否定将这种情况下的表达式强制为实际的 bool(boolean) 值:
let a = 'foo'

if (!!a) {
  console.log('a is truthy!');
}
// Will print 'a is truthy!'.

我的问题:这仅仅是样式问题吗?纯粹是要与阅读代码的人交流,我们真的认识到a不是 bool(boolean) 值,但无论如何我们打算将其评估为 bool(boolean) 值?还是存在a的任何表达式或值,其中if (a)实际上计算出的值与if (!!a)不同的 bool(boolean) 值?

最佳答案

a!!a的真实性将始终相同。

ToBoolean只是静态查找,不会在任何步骤执行任何用户定义的代码。使用 ! 将应用ToBoolean,并取反结果。 if 也应用ToBoolean,并获取结果。两者实际上并没有做更多的事情。由于双重否定是标识,并且如果输入已经为 bool(boolean) 值,则ToBoolean不会更改任何内容,因此它们将始终相同。

TL; DR;以伪代码“ToBoolean(a)=== ToBoolean(booleanNot(ToBoolean(booleanNot(ToBoolean(a)))))”。

请注意,可以在每次查找时对变量进行突变,并产生可能令人困惑的测试,但实际上并不能反驳以上内容。第一次评估后,就可以简单地更改a -无论是否使用!!都没有什么区别:

let x = 0;
let objectEnvironment = { get a() { return x++; } };
with(objectEnvironment){
  if (a) console.log("truthy?");
  if (!!a) console.log("double negated truthy?");
}


如果在上面的示例中交换了a!!a的使用,输出将不会更改。注意 with 在严格模式下已经是一个错误,不应使用。它仅显示GetValue可用于执行用户定义的代码。但是,无论是否未使用逻辑,它都是不可检测的,因此为其设置条件应该行不通。

08-18 01:59