我最近阅读了一些代码,这些代码使用!!
将变量转换为布尔值,以便在if语句中求值。对我来说,这似乎有些多余,因为无论如何该变量都会对其布尔值进行评估。这样做有什么性能上的好处,还是为了获得更好的浏览器支持?
示例代码:
var x = 0;
var atTop = x===window.scrollY;
if(!!atTop){
alert("At the top of the page.");
}
修改:
对于非布尔类型的操作数,我也看到了这一点,但是我一直认为使用if
会始终评估变量的布尔值,因为Javascript中的所有值都是“真实的”或“假”。
示例代码:
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...");
}
答案 0 :(得分:5)
简短答案:不,没有理由。
在您的代码中,它已经是boolean
类型,无需进行转换,然后再次转换,您将始终获得相同的结果。实际上,如果您有任何布尔值(true
或false
),当您将!!
与它们中的任何一个一起使用时,它将转换回其初始值:
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
已回答问题的答案:是的,是一样的。这就是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);
答案 1 :(得分:2)
我想说这主要是为了提高代码的可读性。我怀疑是否会对性能或兼容性产生重大影响(请随时进行测试)
但是在代码可读性方面,这向我暗示此变量以前不是布尔值,但是如果要添加有关此变量的新逻辑,请记住这一点。
>尽管在您的情况下,它已经是布尔值,所以它是100%冗余的,但是我猜只是出于某种原因,有人过度使用了上面的推理,并且/或者在其他地方看到它并复制该模式而没有完全理解它(一个简短的习惯)故事时间:在C#中,您可以通过添加@
将受保护的术语命名为变量名称,因此var @class = "hello";
是一个初级开发者,只是假定 all 需要变量名@
我想知道是否有人假设没有比较运算符的if是否需要在!!
之前作为比较运算符
答案 2 :(得分:1)
在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"
我想这是一种由于上述用例而习惯的习惯,因此在希望解决变量的真实性时总是转换为布尔值。对于我们(人类和程序员)而言,始终遵循一条规则比较容易。即使在周围没人的情况下,您也可以一直在车上使用方向指示灯,或者您可能偶尔(或经常)忘记发信号告知何时应该拥有。
答案 3 :(得分:1)
这完全取决于atTop
变量的值。遵循讨论here。
总而言之,如果atTop
的值与boolean
有所不同,则第一个否定会将其转换为布尔值(取反)。第二次求反将使布尔值返回到原始atTop
值的等效布尔值。
例如,如果atTop
是undefined
,则第一个!
将其变为boolean true
,然后第二个!
将其变为{{1} }(相当于boolean false
的布尔值)
但是,在您的代码中,undefined
值是严格相等的atTop
的结果,这意味着您总是在===
中得到布尔值。因此,您不需要将非布尔值转换为布尔值,因此不需要atTop
。