JavaScript中的双重否定(!!) - 它的作用是什么?

183

可能是重复问题:
JavaScript 中的 !!(非非)运算符是什么?

我遇到了这段代码:

function printStackTrace(options) {
    options = options || {guess: true};
    var ex = options.e || null, guess = !!options.guess;
    var p = new printStackTrace.implementation(), result = p.run(ex);
    return (guess) ? p.guessAnonymousFunctions(result) : result;
}

我不禁想知道为什么要双重否定?是否有其他实现相同效果的替代方法?

(这段代码来自https://github.com/eriwen/javascript-stacktrace/blob/master/stacktrace.js.

3个回答

270

它会转化为布尔值。第一个!对其进行一次取反,将值转换如下:

  • undefined 转化为 true
  • null 转化为 true
  • +0 转化为 true
  • -0 转化为 true
  • '' 转化为 true
  • NaN 转化为 true
  • false 转化为 true
  • 所有其他表达式都转化为 false

然后另一个!再次对其进行取反。这是一种简洁的布尔值转换方式,与ToBoolean相同,因为!定义为其取反。虽然在这里是不必要的,因为它仅用作条件运算符的条件,该运算符将以相同的方式确定真实性。


8
@gdoron说:1 / 0 === Infinity; 1 / -0 === -Infinity。(翻译:@gdoron stated that 1 / 0 === Infinity; 1 / -0 === -Infinity.) - Ry-
7
if(guess)if(!!guess) 是等价的吗?除了展示变量是否为真或假之外,在 JavaScript 中还有哪些情况需要这样做?如果你只在条件表达式或 IF 语句中使用它,似乎这是一个不必要的步骤,因为对象的真实性总是会被求值。这种说法准确吗? - JoePC
7
如果你只在条件表达式或if语句中使用它,那么@JoePC说得没错,这是一个不必要的步骤。 - Ry-
6
谢谢您的信任!在我发布后,我发现了一个很好的示例。 当从函数中返回并需要返回布尔类型而不是对象本身时,例如:return !!guess;,我可以看出先前的用法并不完全必要。(guess = !!option.guess - JoePC
1
我认为如果包括上述关于何时有用以及何时无用的评论,这个答案会更好。 - forgivenson
显示剩余2条评论

69
var x = "somevalue"
var isNotEmpty = !!x.length;

让我们分解一下:

x.length   // 9
!x.length  // false
!!x.length // true

所以它被用来将一个“真值”或“假值”转换为布尔型。


条件语句中,以下值等价于false:

  • false
  • null
  • undefined
  • 空字符串""( \ '')
  • 数字0
  • 数字NaN

所有其他的值都等价于true。


32

双重否定可以将一个"真值"或"假值"转换为布尔值,即truefalse

大多数人熟悉使用真值作为测试:

if (options.guess) {
    // Runs if 'options.guess' is truthy,
}

但这并不一定意味着:

options.guess === true   // Could be, could be not
如果你需要将一个“真值”转换为布尔类型的true值,!!是一个方便的方法:
!!options.guess === true   // Always true if 'options.guess' is truthy

这个回答让它变得清晰明了。我之前也对 truthy 和 boolean 值有同样的疑问。 - melvin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接