是什么意思啊!!运算符在 JavaScript 中做什么?

发布于 2024-10-05 07:25:45 字数 195 浏览 8 评论 0原文

我看到了这段代码:

this.vertical = vertical !== undefined ? !!vertical : this.vertical;

它似乎使用 !! 作为操作符,我不认识。它有什么作用?

I saw this code:

this.vertical = vertical !== undefined ? !!vertical : this.vertical;

It seems to be using !! as an operator, which I don't recognize. What does it do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

旧伤慢歌 2024-10-12 07:25:45

它将Object 转换为boolean。如果它是假的(例如,0nullundefined等),那么它将是false,否则,true

!object  // Inverted Boolean
!!object // Noninverted Boolean, so true Boolean representation

所以 !! 不是一个运算符;只是两次 ! 运算符。

通常更简单:

Boolean(object) // Boolean

现实世界示例“测试 IE 版本”:

const isIE8 = !! navigator.userAgent.match(/MSIE 8.0/);
console.log(isIE8); // Returns true or false

如果您 ⇒

console.log(navigator.userAgent.match(/MSIE 8.0/));
// Returns either an Array or null

但如果您 ⇒

console.log(!!navigator.userAgent.match(/MSIE 8.0/));
// Returns either true or false

It converts Object to boolean. If it was falsy (e.g., 0, null, undefined, etc.), it would be false, otherwise, true.

!object  // Inverted Boolean
!!object // Noninverted Boolean, so true Boolean representation

So !! is not an operator; it's just the ! operator twice.

It is generally simpler to do:

Boolean(object) // Boolean

Real World Example "Test IE version":

const isIE8 = !! navigator.userAgent.match(/MSIE 8.0/);
console.log(isIE8); // Returns true or false

If you ⇒

console.log(navigator.userAgent.match(/MSIE 8.0/));
// Returns either an Array or null

But if you ⇒

console.log(!!navigator.userAgent.match(/MSIE 8.0/));
// Returns either true or false
李白 2024-10-12 07:25:45

这是一种非常晦涩的类型转换方式。

! 表示NOT。所以 !truefalse!falsetrue!0true!1false

因此,您要将一个值转换为布尔值,将其反转,然后再次反转。

    // Maximum Obscurity:
    val.enabled = !!userId;

    // Partial Obscurity:
    val.enabled = (userId != 0) ? true : false;

    // And finally, much easier to understand:
    val.enabled = (userId != 0);

    // Or just
    val.enabled = Boolean(userId);

注意:当涉及到某些边缘情况时(当 userId[],例如)由于 != 运算符的工作方式以及哪些值被视为真实

It's a horribly obscure way to do a type conversion.

! means NOT. So !true is false, and !false is true. !0 is true, and !1 is false.

So you're converting a value to a Boolean, inverting it, and then inverting it again.

    // Maximum Obscurity:
    val.enabled = !!userId;

    // Partial Obscurity:
    val.enabled = (userId != 0) ? true : false;

    // And finally, much easier to understand:
    val.enabled = (userId != 0);

    // Or just
    val.enabled = Boolean(userId);

Note: the middle two expressions aren't exactly equivalent to the first expression when it comes to some edge cases (when userId is [], for example) due to the way the != operator works and what values are considered truthy.

风轻花落早 2024-10-12 07:25:45

!!expr (两个 ! 运算符后跟一个表达式)根据 表达式的真实性

当用于非布尔表达式时它是有意义的。一些示例:

注意:< code>Boolean 函数产生完全相同的结果,并且更具可读性。

          !!false // false
           !!true // true

              !!0 // false
!!parseInt("foo") // false — NaN is falsy
              !!1 // true
             !!-1 // true  — negative number is truthy
          !!(1/0) // true  — Infinity is truthy

             !!"" // false — empty string is falsy
          !!"foo" // true  — non-empty string is truthy
        !!"false" // true  — ...even if it contains a falsy value

     !!window.foo // false — undefined value is falsy
      !!undefined // false — undefined primitive is falsy
           !!null // false — null is falsy

             !!{} // true  — an (empty) object is truthy
             !![] // true  — an (empty) array is truthy

!!expr (two ! operators followed by an expression) returns the primitive true or false depending on the truthiness of the expression.

It makes sense when used on non-boolean expressions. Some examples:

Note: the Boolean function produces the exact same results, and it is more readable.

          !!false // false
           !!true // true

              !!0 // false
!!parseInt("foo") // false — NaN is falsy
              !!1 // true
             !!-1 // true  — negative number is truthy
          !!(1/0) // true  — Infinity is truthy

             !!"" // false — empty string is falsy
          !!"foo" // true  — non-empty string is truthy
        !!"false" // true  — ...even if it contains a falsy value

     !!window.foo // false — undefined value is falsy
      !!undefined // false — undefined primitive is falsy
           !!null // false — null is falsy

             !!{} // true  — an (empty) object is truthy
             !![] // true  — an (empty) array is truthy
少女的英雄梦 2024-10-12 07:25:45

泡些茶:

!! 不是操作员。它是 ! 的双重使用——逻辑“非”运算符。


理论上:

! 确定某个值不为“真”:

  • 事实是 假 不是 true (这就是为什么 !false 结果
    true


  • 事实是 true 不是 false (这就是为什么 !true 结果


!! 确定值的“真实性” not:

  • 事实是 true 不是 not true (这就是为什么 !!true 结果在true

  • 事实是 false 不是不是 false(这就是为什么 !!false 结果为 false)


我们希望在比较中确定的是关于引用值的“真相”,而不是参考本身。有一个用例,我们可能想知道某个值的真实情况,即使我们期望该值是 false (或 falsey),或者如果我们期望该值不能是 boolean 类型。


实践:

考虑一个简洁的函数,通过动态类型(又名“鸭子类型”)。我们希望编写一个函数,如果用户的浏览器支持 HTML5 元素,则返回 true,但我们不希望该函数在以下情况下抛出错误: code>


以下是三种方法:

// this won't tell us anything about HTML5 `<audio>` as a feature
var foo = function(tag, atr) { return document.createElement(tag)[atr]; }

// this won't return true if the feature is detected (although it works just fine)
var bar = function(tag, atr) { return !document.createElement(tag)[atr]; }

// this is the concise, feature-detecting solution we want
var baz = function(tag, atr) { return !!document.createElement(tag)[atr]; }

foo('audio', 'preload'); // returns "auto"
bar('audio', 'preload'); // returns false
baz('audio', 'preload'); // returns true

每个函数接受一个 参数和一个要查找的 attribute ,但它们各自根据比较确定的内容返回不同的值。

但是等等,还有更多!

你们中的一些人可能注意到,在这个特定的示例中,人们可以简单地使用稍微更高效的方法来检查相关对象是否具有属性。有两种方法可以做到这一点:

// the native `hasOwnProperty` method
var qux = function(tag, atr) { return document.createElement(tag).hasOwnProperty(atr); }

// the `in` operator
var quux = function(tag, atr) { return atr in document.createElement(tag); }

qux('audio', 'preload');  // returns true
quux('audio', 'preload'); // returns true

我们离题了...

无论这些情况多么罕见,都可能存在一些场景,其中最简洁、最高效,因此也是获得的首选方法。 >true 来自非布尔值、可能未定义的值确实是通过使用 !! 实现的。希望这可笑地澄清了这一点。

Brew some tea:

!! is not an operator. It is the double-use of ! -- which is the logical "not" operator.


In theory:

! determines the "truth" of what a value is not:

  • The truth is that false is not true (that's why !false results
    in true)

  • The truth is that true is not false (that's why !true results
    in false)


!! determines the "truth" of what a value is not not:

  • The truth is that true is not not true (that's why !!true results in true)

  • The truth is that false is not not false (that's why !!false results in false)


What we wish to determine in the comparison is the "truth" about the value of a reference, not the value of the reference itself. There is a use-case where we might want to know the truth about a value, even if we expect the value to be false (or falsey), or if we expect the value not to be typeof boolean.


In practice:

Consider a concise function which detects feature functionality (and in this case, platform compatibility) by way of dynamic typing (aka "duck typing"). We want to write a function that returns true if a user's browser supports the HTML5 <audio> element, but we don't want the function to throw an error if <audio> is undefined; and we don't want to use try ... catch to handle any possible errors (because they're gross); and also we don't want to use a check inside the function that won't consistently reveal the truth about the feature (for example, document.createElement('audio') will still create an element called <audio> even if HTML5 <audio> is not supported).


Here are the three approaches:

// this won't tell us anything about HTML5 `<audio>` as a feature
var foo = function(tag, atr) { return document.createElement(tag)[atr]; }

// this won't return true if the feature is detected (although it works just fine)
var bar = function(tag, atr) { return !document.createElement(tag)[atr]; }

// this is the concise, feature-detecting solution we want
var baz = function(tag, atr) { return !!document.createElement(tag)[atr]; }

foo('audio', 'preload'); // returns "auto"
bar('audio', 'preload'); // returns false
baz('audio', 'preload'); // returns true

Each function accepts an argument for a <tag> and an attribute to look for, but they each return different values based on what the comparisons determine.

But wait, there's more!

Some of you probably noticed that in this specific example, one could simply check for a property using the slightly more performant means of checking if the object in question has a property. There are two ways to do this:

// the native `hasOwnProperty` method
var qux = function(tag, atr) { return document.createElement(tag).hasOwnProperty(atr); }

// the `in` operator
var quux = function(tag, atr) { return atr in document.createElement(tag); }

qux('audio', 'preload');  // returns true
quux('audio', 'preload'); // returns true

We digress...

However rare these situations may be, there may exist a few scenarios where the most concise, most performant, and thus most preferred means of getting true from a non-boolean, possibly undefined value is indeed by using !!. Hopefully this ridiculously clears it up.

电影里的梦 2024-10-12 07:25:45

!! 将其右侧的值转换为其等效的布尔值。 (想想穷人的“类型转换”方式。)它的意图通常是向读者传达代码并不关心变量中的值是什么,但是它的“真相”值是什么。

!! converts the value to the right of it to its equivalent Boolean value. (Think poor man's way of "type-casting".) Its intent is usually to convey to the reader that the code does not care what value is in the variable, but what its "truth" value is.

放肆 2024-10-12 07:25:45

!!foo 应用一元 not 运算符两次,用于转换为布尔类型,类似于使用一元加 +foo 进行转换转换为数字并连接空字符串 ''+foo 以转换为字符串。

除了这些技巧之外,您还可以使用与原始类型相对应的构造函数(使用new)来显式转换值,即

Boolean(foo) === !!foo
Number(foo)  === +foo
String(foo)  === ''+foo

!!foo applies the unary not operator twice and is used to cast to a Boolean type similar to the use of unary plus +foo to cast to a number and concatenating an empty string ''+foo to cast to a string.

Instead of these hacks, you can also use the constructor functions corresponding to the primitive types (without using new) to explicitly cast values, i.e.,

Boolean(foo) === !!foo
Number(foo)  === +foo
String(foo)  === ''+foo
小女人ら 2024-10-12 07:25:45

这么多答案,事半功倍。是的,!!X 可以理解为“X 的真实性[表示为布尔值]”。但实际上,!! 对于确定单个变量(或者即使许多变量是)真值还是假值来说并不那么重要。 !!myVar === truemyVar 相同。将 !!X 与“真正的”布尔值进行比较并不是很有用。

使用 !! 获得的唯一好处是能够以可重复的、标准化的方式(以及 JSLint 友好)时尚。

简单地转换:(

也就是说...

  • 0 === falsefalse
  • !!0 === falsetrue 上面的代码

不太有用。 if (!0) 给出的结果与 if (!!0 === false) 相同。考虑将变量转换为布尔值然后与“true”布尔值进行比较的好例子,

请参阅 JSLint 的说明(注意:网站已更改;这是存档副本)了解原因:

== 和 != 运算符在比较之前进行类型强制转换。这很糟糕,因为它会导致 ' \t\r\n' == 0 为真。这可以掩盖类型错误。 JSLint 无法可靠地确定 == 是否正确使用,因此最好根本不使用 == 和 !=,而始终使用更可靠的 === 和 !== 运算符。

如果您只关心某个值是真还是假,那么请使用缩写形式。而不是
(foo != 0)

就说
(foo)

而不是
(foo == 0)


(!foo)

请注意,在一些不直观的情况中,布尔值将被转换为将布尔值与数字进行比较时,数字(true 转换为 1false 转换为 0)。在这种情况下,!! 可能在心理上有用。不过,在这些情况下,您将非布尔值与硬类型布尔值进行比较,在我看来,这是一个严重的错误。 if (-1)< /code> 仍然是这里的方法。

原始等效结果注释
if (-1 == true) console.log("spam" )if (-1 == 1)未定义
if (-1 == false) console.log("spam")if (-1 == 0)未定义
if (true == -1) console.log("spam")if (1 == -1)undefined顺序并不重要
...
if (!!-1 == true) console.log("spam")if (true == true)垃圾邮件更好
if (-1) console .log("spam")if (truthy)垃圾邮件仍然是最好的

并且根据您的引擎,事情会变得更加疯狂。例如,WScript 赢得了奖项。

function test()
{
    return (1 === 1);
}
WScript.echo(test());

由于一些历史Windows jive,它将在消息框中输出-1!在 cmd.exe 提示符下尝试一下,看看吧!但是 WScript.echo(-1 == test()) 仍然给你 0,或者 WScript 的 false别看别处。这太可怕了。

比较真实性:)

但是如果我有两个值需要检查是否相等真实性/虚假性怎么办?

假设我们有 myVar1 = 0;myVar2 = undefined;

  • myVar1 === myVar20 === undefined 并且显然是错误的。
  • !!myVar1 === !!myVar2!!0 === !!undefined 并且是真的!同样的真实! (在这种情况下,两者都“具有虚假的真实性”。)

因此,您真正需要使用“布尔转换变量”的唯一地方是,如果您要检查两个变量是否都具有 < em>同样的真实性,对吗?也就是说,如果您需要查看两个变量是都是真值还是都是假(或不是),即相等,则使用!! (或不是)真实性

我想不出一个很好的、非人为的用例来实现这一点。也许您的表单中有“链接”字段?

if (!!customerInput.spouseName !== !!customerInput.spouseAge ) {
    errorObjects.spouse = "Please either enter a valid name AND age "
        + "for your spouse or leave all spouse fields blank.";
}

因此,现在如果您的配偶姓名和年龄都为真,或者都为假,您就可以继续。否则,您只有一个具有值的字段(或很早的包办婚姻),并且需要在您的 errorObjects 集合上创建一个额外的错误。

尽管即使在这种情况下, !! 确实是多余的。一个 ! 足以转换为布尔值,而您只需检查相等性。


编辑 2017 年 10 月 24 日,2 月 6 日:

需要显式布尔值的第三方库

这是一个有趣的案例...当第三方库需要显式布尔值时 !! 可能会很有用显式布尔值。

React

例如,False 在 JSX (React) 中具有特殊含义< /a> 这不是因为简单的错误而触发的。如果您尝试在 JSX 中返回类似以下内容,并且期望 messageCount 中包含 int...

{messageCount &&

你有消息!

}

...当你有零条消息时,你可能会惊讶地看到 React 渲染 0 。您必须显式返回 false 才能使 JSX 不呈现。上面的语句返回 0,JSX 愉快地渲染它,正如它应该的那样。它无法告诉您没有计数:{messageCount}

  • 一个修复涉及 bangbang,它将 0 强制转换为 !!0,即 false
    {!!messageCount &&

    您有消息!

    }

  • JSX 文档建议您更加明确,编写自我注释代码,并使用比较来强制为布尔值。
    <代码>{消息计数> 0 &&

    您有消息!

    }

  • 我自己用三元来处理虚假会更自如 --
    <代码>{消息计数?

    您有消息!

    :假}

TypeScript

TypeScript 中的相同处理:如果您有一个返回布尔值的函数(或者您正在为布尔变量赋值),那么您[通常]无法返回/分配布尔值 - y 值;它必须是强类型布尔值。这意味着,iff myObject 是强类型的return !myObject; 适用于返回布尔值的函数,但return myObject;< /code> 没有。您必须返回!!myObject(或以另一种方式转换为正确的布尔值)才能满足 TypeScript 的期望。

TypeScript 的例外?如果 myObjectany,那么您就回到了 JavaScript 的狂野西部,并且可以在没有 !! 的情况下返回它,即使您的返回类型是布尔值。

请记住,这些是 JSX 和 TypeScript 约定,而不是 JavaScript 固有的

但是,如果您在渲染的 JSX 中看到奇怪的 0,请考虑松散的虚假管理。

So many answers doing half the work. Yes, !!X could be read as "the truthiness of X [represented as a Boolean]". But !! isn't, practically speaking, so important for figuring out whether a single variable is (or even if many variables are) truthy or falsy. !!myVar === true is the same as just myVar. Comparing !!X to a "real" Boolean isn't really useful.

The only thing you gain with !! is the ability to check the truthiness of multiple variables against each other in a repeatable, standardized (and JSLint friendly) fashion.

Simply casting :(

That is...

  • 0 === false is false.
  • !!0 === false is true.

The above's not so useful. if (!0) gives you the same results as if (!!0 === false). I can't think of a good case for casting a variable to Boolean and then comparing to a "true" Boolean.

See "== and !=" from JSLint's directions (note: site has changed; this is an archived copy) for a little on why:

The == and != operators do type coercion before comparing. This is bad because it causes ' \t\r\n' == 0 to be true. This can mask type errors. JSLint cannot reliably determine if == is being used correctly, so it is best to not use == and != at all and to always use the more reliable === and !== operators instead.

If you only care that a value is truthy or falsy, then use the short form. Instead of
(foo != 0)

just say
(foo)

and instead of
(foo == 0)

say
(!foo)

Note that there are some unintuitive cases where a Boolean will be cast to a number (true is cast to 1 and false to 0) when comparing a Boolean to a number. In this case, !! might be mentally useful. Though, again, these are cases where you're comparing a non-Boolean to a hard-typed Boolean, which is, in my opinion, a serious mistake. if (-1) is still the way to go here.

OriginalEquivalentResultNotes
if (-1 == true) console.log("spam")if (-1 == 1)undefined
if (-1 == false) console.log("spam")if (-1 == 0)undefined
if (true == -1) console.log("spam")if (1 == -1)undefinedOrder doesn't
matter...
if (!!-1 == true) console.log("spam")if (true == true)spambetter
if (-1) console.log("spam")if (truthy)spamstill best

And things get even crazier depending on your engine. WScript, for instance, wins the prize.

function test()
{
    return (1 === 1);
}
WScript.echo(test());

Because of some historical Windows jive, that'll output -1 in a message box! Try it in a cmd.exe prompt and see! But WScript.echo(-1 == test()) still gives you 0, or WScript's false. Look away. It's hideous.

Comparing truthiness :)

But what if I have two values I need to check for equal truthiness/falsiness?

Pretend we have myVar1 = 0; and myVar2 = undefined;.

  • myVar1 === myVar2 is 0 === undefined and is obviously false.
  • !!myVar1 === !!myVar2 is !!0 === !!undefined and is true! Same truthiness! (In this case, both "have a truthiness of falsy".)

So the only place you'd really need to use "Boolean-cast variables" would be if you had a situation where you're checking if both variables have the same truthiness, right? That is, use !! if you need to see if two variables are both truthy or both falsy (or not), that is, of equal (or not) truthiness.

I can't think of a great, non-contrived use case for that offhand. Maybe you have "linked" fields in a form?

if (!!customerInput.spouseName !== !!customerInput.spouseAge ) {
    errorObjects.spouse = "Please either enter a valid name AND age "
        + "for your spouse or leave all spouse fields blank.";
}

So now if you have a truthy for both or a falsy for both spouse name and age, you can continue. Otherwise you've only got one field with a value (or a very early arranged marriage) and need to create an extra error on your errorObjects collection.

Though even in this case, the !! really is superfluous. One ! was enough to cast to a Boolean, and you're just checking equality.


EDIT 24 Oct 2017, 6 Feb 19:

Third-party libraries that expect explicit Boolean values

Here's an interesting case... !! might be useful when third-party libraries expect explicit Boolean values.

React

For instance, False in JSX (React) has a special meaning that's not triggered on simple falsiness. If you tried returning something like the following in your JSX, expecting an int in messageCount...

{messageCount && <div>You have messages!</div>}

... you might be surprised to see React render a 0 when you have zero messages. You have to explicitly return false for JSX not to render. The above statement returns 0, which JSX happily renders, as it should. It can't tell you didn't have Count: {messageCount}.

  • One fix involves the bangbang, which coerces 0 into !!0, which is false:
    {!!messageCount && <div>You have messages!</div>}

  • JSX' documentation suggests you be more explicit, write self-commenting code, and use a comparison to force to a Boolean.
    {messageCount > 0 && <div>You have messages!</div>}

  • I'm more comfortable handling falsiness myself with a ternary --
    {messageCount ? <div>You have messages!</div> : false}

TypeScript

The same deal in TypeScript: If you have a function that returns a Boolean (or you're assigning a value to a Boolean variable), you [usually] can't return/assign a boolean-y value; it has to be a strongly typed boolean. This means, iff myObject is strongly typed, return !myObject; works for a function returning a Boolean, but return myObject; doesn't. You have to return !!myObject (or cast to the proper Boolean another way) to match TypeScript's expectations.

The exception for TypeScript? If myObject was an any, you're back in JavaScript's Wild West and can return it without !!, even if your return type is a Boolean.

Keep in mind that these are JSX and TypeScript conventions, not ones inherent to JavaScript.

But if you see strange 0s in your rendered JSX, think loose falsy management.

幸福还没到 2024-10-12 07:25:45

这只是逻辑 NOT 运算符,两次。它用于将某些内容转换为布尔值,例如:

true === !!10

false === !!0

It's just the logical NOT operator, twice. It's used to convert something to Boolean, e.g.:

true === !!10

false === !!0
倾城月光淡如水﹏ 2024-10-12 07:25:45

它将后缀转换为布尔值。

It converts the suffix to a Boolean value.

何处潇湘 2024-10-12 07:25:45

看来 !! 运算符会导致双重否定。

var foo = "Hello, World!";

!foo // Result: false
!!foo // Result: true

It seems that the !! operator results in a double negation.

var foo = "Hello, World!";

!foo // Result: false
!!foo // Result: true
巡山小妖精 2024-10-12 07:25:45

它模拟 Boolean() 转换函数的行为。
第一个 NOT 返回一个布尔值,无论给出什么操作数。第二个 NOT 否定该 Boolean 值,从而给出变量的 true 布尔值。最终结果与对值使用 Boolean() 函数相同。

It simulates the behavior of the Boolean() casting function.
The first NOT returns a Boolean value no matter what operand it is given. The second NOT negates that Boolean value and so gives the true Boolean value of a variable. The end result is the same as using the Boolean() function on a value.

匿名的好友 2024-10-12 07:25:45

这是一个双重not 操作。第一个 ! 将值转换为布尔值并反转其逻辑值。第二个 ! 将逻辑值反转。

It's a double not operation. The first ! converts the value to Boolean and inverts its logical value. The second ! inverts the logical value back.

沙与沫 2024-10-12 07:25:45

!! 一起使用了 NOT 操作两次。 ! 将值转换为布尔值并反转它,因此使用它两次,显示该值的布尔值(假或真)。这是一个简单的例子来看看!!是如何工作的:

首先,你所拥有的地方:

var zero = 0;

然后你做!0。它将被转换为布尔值并被评估为 true,因为 0 是 falsy,所以你得到相反的值并转换为布尔值,因此它被评估为 正确。

!zero; //true

但我们不想要该值的反转布尔版本,因此我们可以再次反转它以获得我们的结果!这就是我们使用另一个 ! 的原因。

基本上, !! 让我们确保我们得到的值是布尔值,而不是假值、真值、字符串等......

所以这就像在 JavaScript 中使用 Boolean 函数,但是将值转换为布尔值的更简单、更短的方法:

var zero = 0;
!!zero; //false

!! is using the NOT operation twice together. ! converts the value to a Boolean and reverses it, so using it twice, showing the Boolean (false or true) of that value. Here is a simple example to see how !! works:

At first, the place you have:

var zero = 0;

Then you do !0. It will be converted to Boolean and be evaluated to true, because 0 is falsy, so you get the reversed value and converted to Boolean, so it gets evaluated to true.

!zero; //true

But we don't want the reversed Boolean version of the value, so we can reverse it again to get our result! That's why we use another !.

Basically, !! makes us sure the value we get is Boolean, not falsy, truthy, string, etc...

So it's like using the Boolean function in JavaScript, but an easier and shorter way to convert a value to Boolean:

var zero = 0;
!!zero; //false
沦落红尘 2024-10-12 07:25:45

!是“布尔非”,它本质上将“enable”的值类型转换为其相反的布尔值。第二个!翻转该值。因此,!!enable 表示“不启用”,为您提供布尔值形式的 enable 值。

! is "Boolean not", which essentially typecasts the value of "enable" to its boolean opposite. The second ! flips this value. So, !!enable means "not not enable," giving you the value of enable as a Boolean.

安静 2024-10-12 07:25:45

我认为值得一提的是,与逻辑 AND/OR 组合的条件不会返回布尔值,但在 && 情况下最后一次成功或第一次失败以及在条件链的 || 的情况。

res = (1 && 2); // res is 2
res = (true && alert) // res is function alert()
res = ('foo' || alert) // res is 'foo'

为了将条件转换为真正的布尔文字,我们可以使用双重否定:

res = !!(1 && 2); // res is true
res = !!(true && alert) // res is true
res = !!('foo' || alert) // res is true

I think worth mentioning is that a condition combined with logical AND/OR will not return a Boolean value, but the last success or first fail in case of && and the first success or last fail in case of || of the condition chain.

res = (1 && 2); // res is 2
res = (true && alert) // res is function alert()
res = ('foo' || alert) // res is 'foo'

In order to cast the condition to a true Boolean literal we can use the double negation:

res = !!(1 && 2); // res is true
res = !!(true && alert) // res is true
res = !!('foo' || alert) // res is true
杀お生予夺 2024-10-12 07:25:45

!! 构造是将任何 JavaScript 表达式转换为
它的布尔等价物。

例如:!!“他击落了我”=== true!!0 === false

The !! construct is a simple way of turning any JavaScript expression into
its Boolean equivalent.

For example: !!"he shot me down" === true and !!0 === false.

瘫痪情歌 2024-10-12 07:25:45

这不是一个单独的操作员;而是一个操作员。是两个。它相当于以下内容,是将值转换为布尔值的快速方法。

val.enabled = !(!enable);

It's not a single operator; it's two. It's equivalent to the following and is a quick way to cast a value to Boolean.

val.enabled = !(!enable);
囚我心虐我身 2024-10-12 07:25:45

它强制所有东西都为布尔值。

例如:

console.log(undefined);   // -> undefined
console.log(!undefined);  // -> true
console.log(!!undefined); // -> false

console.log('abc');   // -> abc
console.log(!'abc');  // -> false
console.log(!!'abc'); // -> true

console.log(0 === false);   // -> false
console.log(!0 === false);  // -> false
console.log(!!0 === false); // -> true

It forces all things to Boolean.

For example:

console.log(undefined);   // -> undefined
console.log(!undefined);  // -> true
console.log(!!undefined); // -> false

console.log('abc');   // -> abc
console.log(!'abc');  // -> false
console.log(!!'abc'); // -> true

console.log(0 === false);   // -> false
console.log(!0 === false);  // -> false
console.log(!!0 === false); // -> true
末蓝 2024-10-12 07:25:45

我怀疑这是 C++ 的遗留问题,人们重写 ! 运算符,但不重写 bool 运算符。

因此,要在这种情况下获得否定(或肯定)答案,您首先需要使用 ! 运算符来获取布尔值,但如果您想检查肯定情况,您将使用 !!

I suspect this is a leftover from C++ where people override the ! operator, but not the bool operator.

So to get a negative (or positive) answer in that case, you would first need to use the ! operator to get a Boolean, but if you wanted to check the positive case you would use !!.

中二柚 2024-10-12 07:25:45

ifwhile 语句以及 ? 运算符使用真值来确定要运行哪个代码分支。例如,零和 NaN 数字以及空字符串为 false,但其他数字和字符串为 true。对象为 true,但未定义值和 null 均为 false。

双重否定运算符 !! 计算某个值的真值。它实际上是两个运算符,其中 !!x 表示 !(!x),其行为如下:

  • 如果 x 是 false 值,则 < code>!x 为 true!!xfalse
  • 如果 x 为 true 值,则 !xfalse!!xtrue< /代码>。

当在布尔上下文的顶层使用时(ifwhile?),!!操作符在行为上是无操作的。例如,if (x)if (!!x) 表示相同的意思。

实际用途

然而它有几个实际用途。

一种用途是将对象有损地压缩为其真值,这样您的代码就不会保留对大对象的引用并保持其活动状态。将 !!some_big_object 分配给变量而不是 some_big_object 可以让垃圾收集器将其释放。这对于产生对象或错误值(例如 null)或未定义值(例如浏览器功能检测)的情况非常有用。

我在关于 C 相应 !! 运算符的答案中提到的另一种用法是“ lint”工具,用于查找常见拼写错误并打印诊断信息。例如,在 C 和 JavaScript 中,布尔运算的一些常见拼写错误会产生其他行为,其输出并不完全是布尔值:

  • if (a = b) 是赋值,然后使用真值bif (a == b) 是相等比较。
  • if (a & b) 是按位与; if (a && b) 是逻辑 AND。 <代码>2 & 5 是 0(假值); <代码>2 && 5 是正确的。

!! 运算符向 lint 工具保证您所写的就是您的意思:执行此操作,然后获取结果的真值。

第三种用途是产生逻辑 XOR 和逻辑 XNOR。在 C 和 JavaScript 中,a && b 执行逻辑 AND(如果两边都为 true,则为 true),而 a & b 执行按位与。 一个 || b 执行逻辑或(如果至少有一个为 true,则为 true),并且 a | b 执行按位或。有一个按位 XOR(异或),如 a ^ b,但没有用于逻辑 XOR 的内置运算符(如果恰好一侧为 true,则为 true)。例如,您可能希望允许用户在两​​个字段之一中输入文本。您可以做的是将每个值转换为真值并进行比较:!!x !== !!y

The if and while statements and the ? operator use truth values to determine which branch of code to run. For example, zero and NaN numbers and the empty string are false, but other numbers and strings are true. Objects are true, but the undefined value and null are both false.

The double negation operator !! calculates the truth value of a value. It's actually two operators, where !!x means !(!x), and behaves as follows:

  • If x is a false value, !x is true, and !!x is false.
  • If x is a true value, !x is false, and !!x is true.

When used at the top level of a Boolean context (if, while, or ?), the !! operator is behaviorally a no-op. For example, if (x) and if (!!x) mean the same thing.

Practical uses

However it has several practical uses.

One use is to lossily compress an object to its truth value, so that your code isn't holding a reference to a big object and keeping it alive. Assigning !!some_big_object to a variable instead of some_big_object lets go of it for the garbage collector. This is useful for cases that produce either an object or a false value such as null or the undefined value, such as browser feature detection.

Another use, which I mentioned in an answer about C's corresponding !! operator, is with "lint" tools that look for common typos and print diagnostics. For example, in both C and JavaScript, a few common typos for Boolean operations produce other behaviors whose output isn't quite as Boolean:

  • if (a = b) is assignment followed by use of the truth value of b; if (a == b) is an equality comparison.
  • if (a & b) is a bitwise AND; if (a && b) is a logical AND. 2 & 5 is 0 (a false value); 2 && 5 is true.

The !! operator reassures the lint tool that what you wrote is what you meant: do this operation, then take the truth value of the result.

A third use is to produce logical XOR and logical XNOR. In both C and JavaScript, a && b performs a logical AND (true if both sides are true), and a & b performs a bitwise AND. a || b performs a logical OR (true if at least one are true), and a | b performs a bitwise OR. There's a bitwise XOR (exclusive OR) as a ^ b, but there's no built-in operator for logical XOR (true if exactly one side is true). You might, for example, want to allow the user to enter text in exactly one of two fields. What you can do is convert each to a truth value and compare them: !!x !== !!y.

初与友歌 2024-10-12 07:25:45

这个问题已经得到了相当彻底的回答,但我想添加一个答案,我希望尽可能简化,使含义!!尽可能简单易懂。

因为 JavaScript 具有所谓的“true”和“falsy”值,所以有些表达式在其他表达式中计算时将导致 true 或 false 条件,即使正在检查的值或表达式实际上不是 true代码> 或<代码>假。

例如:

if (document.getElementById('myElement')) {
    // Code block
}

如果该元素确实存在,则表达式将计算为 true,并且将执行代码块。

但是:

if (document.getElementById('myElement') == true) {
    // Code block
}

...将不会导致条件为真,并且即使该元素确实存在,代码块也不会被执行。

为什么?因为 document.getElementById() 是一个“真实”表达式,在此 if() 语句中计算结果为 true,但它不是 的实际布尔值正确。

在这种情况下,双“不”非常简单。这只是背靠背的两个

第一个只是“反转”真值或假值,产生实际的布尔类型,然后第二个将其再次“反转”回其原始状态,但现在是实际的布尔值。这样你就具有一致性:

if (!!document.getElementById('myElement')) {}

并且

if (!!document.getElementById('myElement') == true) {}

两者返回true,如预期的那样。

This question has been answered quite thoroughly, but I'd like to add an answer that I hope is as simplified as possible, making the meaning of !! as simple to grasp as can be.

Because JavaScript has what are called "truthy" and "falsy" values, there are expressions that when evaluated in other expressions will result in a true or false condition, even though the value or expression being examined is not actually true or false.

For instance:

if (document.getElementById('myElement')) {
    // Code block
}

If that element does in fact exist, the expression will evaluate as true, and the code block will be executed.

However:

if (document.getElementById('myElement') == true) {
    // Code block
}

...will not result in a true condition, and the code block will not be executed, even if the element does exist.

Why? Because document.getElementById() is a "truthy" expression that will evaluate as true in this if() statement, but it is not an actual Boolean value of true.

The double "not" in this case is quite simple. It is simply two nots back to back.

The first one simply "inverts" the truthy or falsy value, resulting in an actual Boolean type, and then the second one "inverts" it back again to its original state, but now in an actual Boolean value. That way you have consistency:

if (!!document.getElementById('myElement')) {}

and

if (!!document.getElementById('myElement') == true) {}

will both return true, as expected.

何以笙箫默 2024-10-12 07:25:45

我只是想补充一点,这

if(variableThing){
  // do something
}

if(!!variableThing){
  // do something
}

但是当某些内容未定义时这可能是一个问题。

// a === undefined, b is an empty object (eg. b.asdf === undefined)
var a, b = {};

// Both of these give error a.foo is not defined etc.
// you'd see the same behavior for !!a.foo and !!b.foo.bar

a.foo 
b.foo.bar

// This works -- these return undefined

a && a.foo
b.foo && b.foo.bar
b && b.foo && b.foo.bar

这里的技巧是 && 链将返回它找到的第一个错误值 - 并且可以将其提供给 if 语句等。因此,如果 b .foo 未定义,它将返回 undefined 并跳过 b.foo.bar 语句,并且我们不会收到错误。

上面的返回未定义,但如果你有一个空字符串、false、null、0、未定义,这些值将返回,当我们在链中遇到它们时 - []{}< /code> 都是“真实的”,我们将继续沿着所谓的“&&链”向下到达右侧的下一个值。

PS 执行上述操作的另一种方法 (b && b.foo) 是 (b || {}).foo。这些是等效的,因为如果 b 未定义,则 b || {} 将是 {},您将访问空对象中的值(无错误),而不是尝试访问“undefined”中的值(导致错误) 。

因此,(b || {}).foob && 相同。 b.foo((b || {}).foo || {}).barb && 相同b.foo && b.foo.bar

I just wanted to add that

if(variableThing){
  // do something
}

is the same as

if(!!variableThing){
  // do something
}

But this can be an issue when something is undefined.

// a === undefined, b is an empty object (eg. b.asdf === undefined)
var a, b = {};

// Both of these give error a.foo is not defined etc.
// you'd see the same behavior for !!a.foo and !!b.foo.bar

a.foo 
b.foo.bar

// This works -- these return undefined

a && a.foo
b.foo && b.foo.bar
b && b.foo && b.foo.bar

The trick here is the chain of &&s will return the first falsey value it finds -- and this can be fed to an if statement etc. So if b.foo is undefined, it will return undefined and skip the b.foo.bar statement, and we get no error.

The above return undefined but if you have an empty string, false, null, 0, undefined those values will return and soon as we encounter them in the chain -- [] and {} are both "truthy" and we will continue down the so-called "&& chain" to the next value to the right.

P.S. Another way of doing the above (b && b.foo) is (b || {}).foo. Those are equivalent, because if b is undefined then b || {} will be {}, and you'll be accessing a value in an empty object (no error) instead of trying to access a value within "undefined" (causes an error).

So, (b || {}).foo is the same as b && b.foo and ((b || {}).foo || {}).bar is the same as b && b.foo && b.foo.bar.

三生池水覆流年 2024-10-12 07:25:45

它是双重布尔否定。它通常用于检查值是否未定义。

It is double Boolean negation. It is often used to check if a value is not undefined.

成熟稳重的好男人 2024-10-12 07:25:45

这里有很多很好的答案,但如果你已经读到这里,这会帮助我“明白”。在 Chrome(等)中打开控制台,然后开始输入:

!(!(1))
!(!(0))
!(!('truthy')) 
!(!(null))
!(!(''))
!(!(undefined))
!(!(new Object())
!(!({}))
woo = 'hoo'
!(!(woo))
...etc., etc., until the light goes on ;)

当然,这些都与仅输入 !!someThing 相同,但添加的括号可能有助于使其更容易理解。

There are tons of great answers here, but if you've read down this far, this helped me to 'get it'. Open the console in Chrome (etc.), and start typing:

!(!(1))
!(!(0))
!(!('truthy')) 
!(!(null))
!(!(''))
!(!(undefined))
!(!(new Object())
!(!({}))
woo = 'hoo'
!(!(woo))
...etc., etc., until the light goes on ;)

Naturally, these are all the same as merely typing !!someThing, but the added parentheses might help make it more understandable.

阳光的暖冬 2024-10-12 07:25:45

!!xBoolean(x) 的简写。

第一个爆炸强制 JavaScript 引擎运行 Boolean(x),但它也有反转值的副作用。所以第二次爆炸消除了副作用。

!!x is shorthand for Boolean(x).

The first bang forces the JavaScript engine to run Boolean(x), but it also has the side effect of inverting the value. So the second bang undoes the side effect.

已下线请稍等 2024-10-12 07:25:45

看到所有这些精彩的答案后,我想添加使用 !! 的另一个原因。目前我正在使用 Angular 2-4 (TypeScript),当我的用户未经过身份验证时,我想返回一个布尔值 false 。如果他未通过身份验证,则令牌字符串将为 null""。我可以使用下一个代码块来做到这一点:

public isAuthenticated(): boolean {
   return !!this.getToken();
}

After seeing all these great answers, I would like to add another reason for using !!. Currently I'm working in Angular 2-4 (TypeScript) and I want to return a Boolean as false when my user is not authenticated. If he isn't authenticated, the token-string would be null or "". I can do this by using the next block of code:

public isAuthenticated(): boolean {
   return !!this.getToken();
}
蓝色星空 2024-10-12 07:25:45

请务必记住 JavaScript 中对 truefalse 的评估:

  • 所有具有“值”的内容都是 true< /code>(即truthy),例如:

    • 101
    • 3.1415
    • <代码>-11,
    • “幸运大脑”
    • new Object()
    • 当然,true

  • 一切都没有“Value”为false(即falsy),例如:

    • 0,
    • <代码>-0,
    • ""(空字符串),
    • 未定义
    • NaN(不是数字)
    • 当然还有

应用“逻辑非”运算符 (!) 计算操作数,将其转换为 boolean,然后对其求反。应用两次将会对负数取反,从而有效地将值转换为布尔值。不应用运算符将​​只是精确值的常规分配。示例:

var value = 23; // number
var valueAsNegatedBoolean = !value; // boolean falsy (because 23 is truthy)
var valueAsBoolean = !!value; // boolean truthy
var copyOfValue = value; // number 23

var value2 = 0;
var value2AsNegatedBoolean = !value2; // boolean truthy (because 0 is falsy)
var value2AsBoolean = !!value2; // boolean falsy
var copyOfValue2 = value2; // number 0
  • value2 = value; 分配精确的对象 value,即使它不是 boolean,因此 value2 不会最终必然是布尔值。
  • value2 = !!value; 分配一个有保证的 boolean 作为操作数 value 双重否定的结果,它等价于以下但更短且可读:
if (value) {
  value2 = true;
} else {
  value2 = false;
}

It is important to remember the evaluations to true and false in JavaScript:

  • Everything with a "Value" is true (namely truthy), for example:

    • 101,
    • 3.1415,
    • -11,
    • "Lucky Brain",
    • new Object()
    • and, of course, true
  • Everything without a "Value" is false (namely falsy), for example:

    • 0,
    • -0,
    • "" (empty string),
    • undefined,
    • null,
    • NaN (not a number)
    • and, of course, false

Applying the "logical not" operator (!) evaluates the operand, converting it to boolean and then negating it. Applying it twice will negate the negation, effectively converting the value to boolean. Not applying the operator will just be a regular assignment of the exact value. Examples:

var value = 23; // number
var valueAsNegatedBoolean = !value; // boolean falsy (because 23 is truthy)
var valueAsBoolean = !!value; // boolean truthy
var copyOfValue = value; // number 23

var value2 = 0;
var value2AsNegatedBoolean = !value2; // boolean truthy (because 0 is falsy)
var value2AsBoolean = !!value2; // boolean falsy
var copyOfValue2 = value2; // number 0
  • value2 = value; assigns the exact object value even if it is not boolean hence value2 won't necessarily end up being boolean.
  • value2 = !!value; assigns a guaranteed boolean as the result of the double negation of the operand value and it is equivalent to the following but much shorter and readable:

if (value) {
  value2 = true;
} else {
  value2 = false;
}

你又不是我 2024-10-12 07:25:45

这是来自 AngularJS 的一段代码:

var requestAnimationFrame = $window.requestAnimationFrame ||
                            $window.webkitRequestAnimationFrame ||
                            $window.mozRequestAnimationFrame;

var rafSupported = !!requestAnimationFrame;

他们的目的是根据 requestAnimationFrame 中函数的可用性将 rafSupported 设置为 true 或 false。

一般来说,可以通过以下方式检查来实现:

if(typeof requestAnimationFrame === 'function')
    rafSupported =true;
else
    rafSupported =false;

简短的方法可以使用 !!

rafSupported = !!requestAnimationFrame;

因此,如果 requestAnimationFrame 被分配了一个函数,那么 !requestAnimationFrame 将为 false,并且还有一个 ! 是真的。

如果 requestAnimationFrame 未定义,则 !requestAnimationFrame 将为 true,而其中的一个 ! 将为 false。

Here is a piece of code from AngularJS:

var requestAnimationFrame = $window.requestAnimationFrame ||
                            $window.webkitRequestAnimationFrame ||
                            $window.mozRequestAnimationFrame;

var rafSupported = !!requestAnimationFrame;

Their intention is to set rafSupported to true or false based on the availability of function in requestAnimationFrame.

It can be achieved by checking in the following way in general:

if(typeof requestAnimationFrame === 'function')
    rafSupported =true;
else
    rafSupported =false;

The short way could be using !!

rafSupported = !!requestAnimationFrame;

So if requestAnimationFrame was assigned a function then !requestAnimationFrame would be false and one more ! of it would be true.

If requestAnimationFrame was assigned undefined then !requestAnimationFrame would be true and one more ! of it would be false.

青萝楚歌 2024-10-12 07:25:45

使用逻辑非运算符两次。

这意味着 !true = false !!true = true

Use the logical not operator two times.

It means !true = false and !!true = true.

吾性傲以野 2024-10-12 07:25:45

它返回变量的布尔值。

相反,可以使用 Boolean 类。

(请阅读代码说明。)

var X = "test"; // The X value is "test" as a String value
var booleanX = !!X // booleanX is `true` as a Boolean value because non-empty strings evaluates as `true` in Boolean
var whatIsXValueInBoolean = Boolean(X) // whatIsXValueInBoolean is `true` again
console.log(Boolean(X) === !!X) // Writes `true`

即使用Boolean(X) = !!X

请检查下面的代码片段

let a = 0
console.log("a: ", a) // Writes a value in its kind
console.log("!a: ", !a) // Writes '0 is NOT true in Boolean' value as Boolean - so that's true. In Boolean, 0 means false and 1 means true.
console.log("!!a: ", !!a) // Writes 0 value in Boolean. 0 means false.
console.log("Boolean(a): ", Boolean(a)) // Equals `!!a`
console.log("\n") // Newline

a = 1
console.log("a: ", a)
console.log("!a: ", !a)
console.log("!!a: ", !!a) // Writes 1 value in Boolean
console.log("\n") // Newline

a = ""
console.log("a: ", a)
console.log("!a: ", !a) // Writes '"" is NOT true in Boolean' value as Boolean - so that's true. In Boolean, empty strings, null and undefined values mean false and if there is a string it means true.
console.log("!!a: ", !!a) // Writes "" value in Boolean
console.log("\n") // Newline

a = "test"
console.log("a: ", a) // Writes a value in its kind
console.log("!a: ", !a)
console.log("!!a: ", !!a) // Writes "test" value in Boolean

console.log("Boolean(a) === !!a: ", Boolean(a) === !!a) // writes true

It returns the Boolean value of a variable.

Instead, the Boolean class can be used.

(Please read the code descriptions.)

var X = "test"; // The X value is "test" as a String value
var booleanX = !!X // booleanX is `true` as a Boolean value because non-empty strings evaluates as `true` in Boolean
var whatIsXValueInBoolean = Boolean(X) // whatIsXValueInBoolean is `true` again
console.log(Boolean(X) === !!X) // Writes `true`

Namely, Boolean(X) = !!X in use.

Please check code snippet out below

let a = 0
console.log("a: ", a) // Writes a value in its kind
console.log("!a: ", !a) // Writes '0 is NOT true in Boolean' value as Boolean - so that's true. In Boolean, 0 means false and 1 means true.
console.log("!!a: ", !!a) // Writes 0 value in Boolean. 0 means false.
console.log("Boolean(a): ", Boolean(a)) // Equals `!!a`
console.log("\n") // Newline

a = 1
console.log("a: ", a)
console.log("!a: ", !a)
console.log("!!a: ", !!a) // Writes 1 value in Boolean
console.log("\n") // Newline

a = ""
console.log("a: ", a)
console.log("!a: ", !a) // Writes '"" is NOT true in Boolean' value as Boolean - so that's true. In Boolean, empty strings, null and undefined values mean false and if there is a string it means true.
console.log("!!a: ", !!a) // Writes "" value in Boolean
console.log("\n") // Newline

a = "test"
console.log("a: ", a) // Writes a value in its kind
console.log("!a: ", !a)
console.log("!!a: ", !!a) // Writes "test" value in Boolean

console.log("Boolean(a) === !!a: ", Boolean(a) === !!a) // writes true

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文