双感叹号?

IT技术 javascript
2021-03-10 22:28:03

可能的重复:
什么是!!(不是)JavaScript 中的运算符?
有什么用!!运算符(双感叹号)在 JavaScript 中是什么意思?

所以我正在调试一些代码并遇到了这个:

var foo.bar = 0; // this is actually passed from another function, adding it for context

function(foo) {
    var someVar = !!foo.bar;

    if (foo.bar) {
      // ..stuff happens
    } else {
      // .. something else happens
    }
}

好的,我的问题是什么!!所做的就是制作0 === false.

  1. 与 相比,使用它有什么好处boolean(foo.bar)吗?

  2. foo.bar 可以在 if 中进行评估,因为0 === false已经如此,那么为什么要进行转换?( someVar 不会在其他任何地方重用)

3个回答

这会将值转换为布尔值并确保布尔类型

"foo"      // Evaluates to "foo".
!"foo"     // Evaluates to false.
!!"foo"    // Evaluates to true.

如果foo.bar通过,则它可能不是 0,而是其他一些假值。请参阅以下真值表:

javascript真值表

''        ==   '0'           // false
0         ==   ''            // true
0         ==   '0'           // true
false     ==   'false'       // false
false     ==   '0'           // true
false     ==   undefined     // false
false     ==   null          // false
null      ==   undefined     // true
" \t\r\n" ==   0             // true

资料来源:道格·克罗克福德

当涉及到 NaN 值时,Javascript 也变得非常奇怪。这是我能想到的唯一一个案例!与 === 的行为不同。

NaN   ===  NaN     //false
!!NaN === !!NaN    //true

// !!NaN is false
@ruakh if 语句是隐式的,不会使用 ===
2021-04-18 22:28:03
@ruakh 我明白这是没有意义的。我试图与 OP 发布的代码联系起来,if foo.bar但是除了我可以推测的偏好之外,唯一的原因是在处理 NaN 时。我已将此编辑为我的答案。
2021-04-23 22:28:03
对不起,你能详细说明一下你最后的评论吗?因为我真的不明白它想表达什么意思。:-/
2021-04-30 22:28:03
@makhdumi:==总是导致trueor false,因此更长的表达式是多余的:x == truex == true ? true : false.
2021-05-10 22:28:03
这实际上并没有回答这个问题。问题是:“foo.bar 可以在 if 中被评估,因为 0 === false 已经,那么为什么要进行转换?” 你的回答解释这确保了布尔类型,但OP已经知道了; 问题是,什么是确保布尔类型?
2021-05-12 22:28:03

我认为答案是没有太多意义。我们可以推测它是如何产生的:

  • 可能是someVar在多个地方使用的函数的早期版本,或者以真正受益于true或 的方式false,所以这更有意义。
  • 也许编写函数的人习惯于使用!!转换为true/false以至于他甚至没有注意到这里没有必要。
  • 也许编写函数的人认为每个计算(在这种情况下,布尔转换)都应该通过为其结果分配一些变量来赋予一个有意义的名称。
  • 也许,因为 JavaScript 中的布尔转换出人意料地容易出错(因为 egnew Boolean(false)是一个真值),编写函数的人认为它应该总是显式而不是隐式地完成——即使效果是一样的——只是为了引起注意它是一个潜在的错误点。
    • 当然,这以编写函数的人认为!!是“显式”布尔转换为前提从技术上讲,它不是——它使用相同的隐式布尔转换if——但如果你习惯了这个习语,那么它就相当于一个显式转换。

但在我的主观看来,这些理由都​​不是一个很好的理由!

我认为这比接受的答案更好,因为它实际上解释了为什么在 OP 要求时可能使用双感叹号,而不仅仅是解释它的作用。我认为说明这一点会有所帮助!!给你一个布尔值,而 new Boolean() 给你一个布尔对象。
2021-04-17 22:28:03
@AngryCub:回复:“OP 特别询问Boolean(exp)”:哦!我想我什至没有注意到那条线。(Mea culpa。查看编辑历史记录,我发现当时它的格式并不那么突出,但仍然如此。)我提到的new Boolean(false)只是作为一个例子,说明 JavaScript 布尔转换规则是多么违反直觉;它与 OP 询问的其他内容有些相似,这只是巧合。
2021-04-21 22:28:03
这尤其重要,让我更喜欢这个答案;“(例如 new Boolean(false) 是一个真值),”
2021-04-27 22:28:03
这可能没有被正确记录在OP的时间,但是(new Boolean(false)) == false同时(new Boolean(false)) !== false因为new Boolean(false)创建一个对象。正如 Mozilla 的文档中所述,如果要转换为布尔值,则必须Boolean(expression)改用。developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
2021-04-27 22:28:03
(new Boolean(false)) == false 在铬 73...
2021-05-06 22:28:03

如上所述,它强制使用布尔类型的对象。你可以亲眼看看:

    (function typecheck() {
      var a = "a";
      var b = !a;
      var c = !!a;
    
      console.log("var a =", a, typeof(a))
      console.log("var b =", b, typeof(b))
      console.log("var c =", c, typeof(c))
    })();

如果您只是进行比较,那么转换只会在以后为您节省类型强制。

仅供参考,以下值在 JavaScript 中被强制为 FALSE:

  • 错误的
  • 0
  • “”
  • 空值
  • 不明确的
比较规则有点奇怪。 这是一个很好的深入解释在你给出的例子中,你会得到一个参考错误是正确的。
2021-04-24 22:28:03
“强制为 FALSE”是指如果我这样做:var b = (nullthing) ? 'sad' : 'happy'如果 nullthing 为 0、null、未定义的空白或假,我可以可靠地得到 b = 'happy' 之类的东西?我可以发誓我遇到过问题,它抱怨在这些类型的情况下它是 undefined 或 null。
2021-05-12 22:28:03