【问题标题】:Double exclamation points? [duplicate]双感叹号? [复制]
【发布时间】:2012-03-06 06:43:14
【问题描述】:

可能重复:
What is the !! (not not) operator in JavaScript?
What does the !! operator (double exclamation point) mean in 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 不会在其他任何地方重用)

【问题讨论】:

  • 好吧,我知道它的作用,我只是想知道您的链接问题中没有解释的好处是什么。
  • 0==false not 0===false 三等号可防止隐式转换尝试。

标签: javascript


【解决方案1】:

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

"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

资料来源:Doug Crockford

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

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

// !!NaN is false

【讨论】:

  • 这实际上并没有回答问题。问题问:“foo.bar 可以在 if 中进行评估,因为 0 === false 已经是,所以为什么要进行转换?”您的回答解释了 它确保了 Boolean 类型,但 OP 已经知道这一点;问题是,确保布尔类型的point是什么?
  • @ruakh if 语句是隐式的,不会使用 ===
  • 抱歉,您能否详细说明您最后的评论?因为我真的不明白它试图说明什么。 :-/
  • @ruakh 我明白这没有任何意义。我试图将代码 OP 与 if foo.bar 发布的代码联系起来,但是除了偏好之外,我可以推测的唯一原因是在处理 NaN 时。我已将其编辑到我的答案中。
  • @makhdumi: == 总是导致truefalse,因此更长的表达式是多余的:x == truex == true ? true : false 的结果完全相同。
【解决方案2】:

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

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

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

【讨论】:

  • 这特别相关,让我更喜欢这个答案; “(例如 new Boolean(false) 是一个真值),”
  • 我认为这比公认的答案更好,因为它实际上解释了为什么双感叹号可能已按照 OP 的要求使用,而不仅仅是解释它的作用。我认为这会有所帮助!给你一个布尔值,而 new Boolean() 给你一个布尔对象。
  • (new Boolean(false)) == false 在 chrome 73 中...
  • 这在 OP 时可能没有正确记录,但是 (new Boolean(false)) == false(new Boolean(false)) !== false 因为 new Boolean(false) 创建了一个对象。如 Mozilla 的文档中所述,如果要转换为布尔值,则必须改用 Boolean(expression)developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • @AngryCub:回复:“OP 专门询问Boolean(exp)”:哦!我想我什至没有注意到那条线。 (过失。查看编辑历史记录,我发现当时它的格式不那么显眼,但仍然如此。)我提到new Boolean(false) 只是为了说明 JavaScript 布尔转换规则有多么违反直觉。这只是一个巧合,它与 OP 询问的其他内容有些相似。
【解决方案3】:

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

    (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
  • ""
  • 未定义

【讨论】:

  • “强制为 FALSE”是指如果我这样做:var b = (nullthing) ? 'sad' : 'happy' 如果 nullthing 为 0、null、未定义的空白或 false,我可以可靠地得到 b = 'happy'?我可以发誓我遇到过问题,它抱怨在这些类型的情况下它是 undefined 或 null。
  • 比较规则有点奇怪。 Here is a good in-depth explanation。在你给出的例子中,你会得到一个参考错误是正确的。
猜你喜欢
  • 2012-07-07
  • 1970-01-01
  • 2015-06-01
  • 2022-01-03
  • 2021-11-02
  • 1970-01-01
  • 2011-05-29
  • 1970-01-01
相关资源
最近更新 更多