何时在 JavaScript 中使用双非 (!!) 运算符
Posted
技术标签:
【中文标题】何时在 JavaScript 中使用双非 (!!) 运算符【英文标题】:When to use the double not (!!) operator in JavaScript 【发布时间】:2011-01-11 13:42:03 【问题描述】:我了解what the double not operator does in javascript。我很好奇它的用途以及我最近的断言是否正确。
我说if (!!someVar)
从来没有意义,(!!someVar && ...
也没有意义,因为if
和&&
都会导致 someVar 被评估为布尔值,所以 !!是多余的。
事实上,我唯一能想到使用 double not 运算符是合法的情况是,如果您想与另一个布尔值进行严格比较(因此可能在返回值中明确地期望 true 或 false )。
这是正确的吗?当我注意到 jQuery 1.3.2 同时使用了if (!!someVar)
和return !!someVar && ...
时,我开始怀疑自己
double 在这些情况下没有任何实际效果吗?
我个人的看法是,它只会导致混乱。如果我看到一个 if 语句,我知道它会将其评估为布尔值。
【问题讨论】:
请注意(正如贾斯汀在回答您引用的问题 ***.com/questions/1406604/… 中指出的那样),没有双非运算符。!!
只应用了两次非运算符。
这个“运算符”是惯用语的定义……除非您知道它是什么,否则您可能会感到困惑或只是将其误读为单个“非”。我将开始使用它来迷惑我的同事:D 如果有人感兴趣,我在 jQuery.grep 中的“wild”中看到了这个
相关:What is the difference between if(!!condition) and if(condition)
另见Why use if (!!err)
?和Why use !!
to coerce a variable to boolean for use in a conditional expression?
【参考方案1】:
在 if
statements 我和你在一起的上下文中,它是完全安全的,因为在内部,ToBoolean
操作将在条件表达式上执行(请参阅规范中的第 3 步) .
但是如果你想,比如说,从一个函数返回一个布尔值,你应该确保结果实际上是布尔值,例如:
function isFoo ()
return 0 && true;
console.log(isFoo()); // will show zero
typeof isFoo() == "number";
总之,Boolean Logical Operators 可以返回一个操作数,而不一定是Boolean
结果:
逻辑与运算符 (&&
) 将返回 第二个操作数 的值,如果第一个是真正:
true && "foo"; // "foo"
如果它本身是falsy,它将返回第一个操作数的值:
NaN && "anything"; // NaN
0 && "anything"; // 0
另一方面,逻辑或运算符 (||
) 将返回 第二个操作数 的值,如果第一个是 falsy:
false || "bar"; // "bar"
如果它本身是非假的,它将返回第一个操作数的值:
"foo" || "anything"; // "foo"
也许值得一提的是,falsy 值是:null
、undefined
、NaN
、0
、零长度字符串,当然还有false
。
在boolean context 中评估的任何其他内容(不是falsy、Boolean
对象或Boolean
值)都将返回true
。
【讨论】:
另一种说法:逻辑 AND 运算符返回遇到的第一个“假”操作数,而逻辑 OR 运算符返回第一个“真”操作数。此外,为了完整起见,-0 也被认为是“虚假的”。 如果您需要!!expr
某些东西,请考虑将其写成Boolean(expr)
,以提高可读性,因为它在功能上是等效的。
这是我经常遇到的一个用例:JSX 中的短路渲染。如果您尝试渲染零长度数组的元素,最终可能会渲染“0”。我做了一个codepen来演示:codepen.io/lucask42/full/GGbqdv【参考方案2】:
是的,当你想要 0||1 返回值时使用 !!var。
一个是布尔值的简单比较,当您希望“a == b”等效于“a xor not b”时,除了 a=5 和 b=7 都为真但不相等。
另一个是当您想将一组条件强制转换为变量的位时:
var BIT_NONEMPTY=1;
var BIT_HASERRORS=2;
var BIT_HASCHILDREN=4;
var BIT_HASCONTENT=8;
result_bitfields =
(!!countLines())*BIT_NOTEMPTY +
(!!errorCode())*BIT_HASERRORS +
(!!firstChild())*BIT_HASCHILDREN +
(!!getContent())*BIT_HASCONTENT;
在与位值相差甚远的 Javascript 中不是很有用,但有时可能很有用。
【讨论】:
否:!!转换为 false 或 true,而不是 0 或 1。(在您的位域示例中,true 被 * 运算符强制为 1,false 为 0)。以上是关于何时在 JavaScript 中使用双非 (!!) 运算符的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Javascript 在 Chrome 中检测选项卡何时聚焦或不聚焦?
在 Javascript 中,何时创建新范围? (使用新功能并在“with”语句中)只有这两种情况吗?