为什么在if语句中使用双惊叹号?

Zam*_*oni 9 javascript if-statement

我最近阅读了一些代码,用于!!将变量转换为boolean以便在if语句中进行求值.这对我来说似乎有些多余,因为无论如何都要对变量进行布尔值的评估.这样做有什么性能优势,还是为了更好的浏览器支持?

示例代码:

var x = 0;
var atTop = x===window.scrollY;
if(!!atTop){
   alert("At the top of the page.");
}
Run Code Online (Sandbox Code Playgroud)

编辑:

我也看过这个不是布尔类型的操作数,但是我总是假设使用它if会评估变量的布尔值,因为Javascript中的所有值都是"truthy"或"falsey".

示例代码:

var x = 1;//or any other value including null, undefined, some string, etc
if(!!x){//x is "truthy"
   //wouldn't using if(x) be the same???
   console.log("something...");
}
Run Code Online (Sandbox Code Playgroud)

Com*_*ide 5

简答:不,没有理由.

在你的代码,它已经是一个boolean类型,没有必要将其转换,并再次转换,你总是会得到相同的结果.实际上,如果您有任何布尔值(truefalse),当您使用!!其中任何一个时,它将被转换回它的初始值:

console.log(!!true); // Will be always "true"
console.log(typeof !!true); // It stills a "boolean" type
console.log(!!false); // Will be always "false"
console.log(typeof !!false); // It stills a "boolean" type
Run Code Online (Sandbox Code Playgroud)

编辑问题的答案:是的,它是一样的.这就是if(...)实际做的 - 它试图将任何类型转换为boolean.

这里是一个小测试,你可以玩与并添加任何你想要的内部initialArr阵列进行测试,它的表现同样与if!!:

const initialArr = [
  undefined,
  null,
  true,
  false,
  0,
  3,
  -1,
  +Infinity,
  -Infinity,
  Infinity,
  'any',
  '',
  function() { return 1 },
  {},
  { prop: 1 },
  [],
  [0],
  [0, 1]
];

function testIsTheSame(arr) {
  equolityCounter = 0;
  arr.forEach(item => {
    let ifStatement = false;
    let doubleNotStatement = !!item;
    if(item) {
      ifStatement = true;
    }

    if(ifStatement === doubleNotStatement && typeof ifStatement === typeof doubleNotStatement) {
      equolityCounter++;
    }
  });
  console.log(`Is the same: ${equolityCounter === arr.length}`);
}

testIsTheSame(initialArr);
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢您的解释. (2认同)

Ben*_*kay 5

在 if 语句中执行此操作没有任何运行时好处(或客观好处)。if 语句执行的评估将产生与双感叹号产生的评估完全相同的结果。没有区别。

双感叹号是确保布尔值基于真实性的有用表达式。例如,考虑一下:

var text = undefined;
console.log(text); // undefined
console.log(!!text); // false

// It would make sense here, because a boolean value is expected.
var isTextDefined = !!text;

// It would also affect serialization
JSON.stringify(text); // undefined (non-string)
JSON.stringify(!!text); // "false"
Run Code Online (Sandbox Code Playgroud)

我认为这是由于上述用例而养成的习惯,因此当希望解决变量的真实性时总是转换为布尔值。当规则始终被应用时,我们(人类和程序员)更容易遵循它。您要么会一直在车里使用方向灯,即使周围没有人,要么您可能偶尔(或可能经常)忘记在应该打信号时打信号。