web-dev-qa-db-ja.com

何ですか! JavaScriptの(ではない)演算子?

!!のように、2つの感嘆符の形で、認識できない演算子を使用しているようなコードをいくつか見ました。誰かがこの演算子が何をするのか教えてもらえますか?

私がこれを見た文脈は、

this.vertical = vertical !== undefined ? !!vertical : this.vertical;
2697
Hexagon Theory

oObjectをブール値に強制変換します。もしそれが偽であれば(例えば0、nullundefinedなど)、それはfalseになり、そうでなければtrueになります。

!oObject  //Inverted boolean
!!oObject //Non inverted boolean so true boolean representation

したがって、!!は演算子ではなく、単なる!演算子です.

実際の例 "Test IE version": 

let isIE8 = false;  
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
2354
stevehipwell

それは型変換をするための恐ろしく曖昧な方法です。

! _ではなく_ です。したがって、!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);
786
Tom Ritter

!!exprは式の 真実性 に応じてブール値(trueまたはfalse)を返します。非ブール型で使用するとより意味があります。これらの例、特に3番目以降の例を考えてください。

          !!false === false
           !!true === true

              !!0 === false
!!parseInt("foo") === false // NaN is falsy
              !!1 === true
             !!-1 === true  // -1 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 is falsy
           !!null === false // null is falsy

             !!{} === true  // an (empty) object is truthy
             !![] === true  // an (empty) array is truthy; PHP programmers beware!
410
Salman A

お茶をrewれる:

!!は演算子ではありません。これは!の二重使用です。これは論理的な「否定」演算子です。


理論上:

!は、値がそうでないものの「真実」を決定します。

  • 真実は、falsetrueではないということです(だから!falsetrueになります)

  • 真実は、truefalseではないということです(だから!truefalseになります)


!!は、値がnotでない「真」を決定します。

  • 真実は、truenotではないということです_true(だからこそ!!truetrueになります)

  • 真実は、falsenotではないということです_false(だからこそ!!falsefalseになります)


比較で決定したいのは、参照自体のの値ではなく、参照の値である「真実」aboutです。値がfalse(またはfalsey)であると予想される場合、または値がbooleanであると予想されない場合でも、値についての真実を知りたいユースケースがあります。


実際には:

動的タイピング(別名「アヒルタイピング」)。ユーザーのブラウザーがHTML5の<audio>要素をサポートしている場合はtrueを返す関数を作成しますが、<audio>が定義されていない場合は関数がエラーをスローしないようにします。そして、try ... catchを使用して、発生する可能性のあるエラーを処理したくありません(それらは大規模なため)。 および関数内で、機能に関する一貫した真実を一貫して明らかにしないチェックを使用したくない(たとえば、document.createElement('audio')は、HTML5であっても<audio>という要素を作成します<audio>はサポートされていません)。


以下に3つのアプローチを示します。

// 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

各関数は、検索する<tag>およびattributeの引数を受け入れますが、それぞれが比較の決定内容に基づいて異なる値を返します。

しかし、待って、まだあります!

おそらく、この特定の例では、わずかにmore performanceantの手段を使用してプロパティを簡単に確認できることに気づいた人もいるでしょう。問題のオブジェクトhasがプロパティかどうかを確認します。これを行うには2つの方法があります。

// 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を取得するための最も好ましい手段が実際に!!を使用するいくつかのシナリオが存在する場合があります。うまくいけば、これはばかげてそれをクリアします。

142
Benny

!!は、その右側の値をそれと等価のブール値に変換します。 (貧乏人の「タイプキャスティング」の方法を考えてください)。そのintentは通常、コードが変数内のwhat値を気にする必要はないことを読者に伝えるためのものですが、それは "true" value です.

91
Crescent Fresh

!!fooは単項not演算子を2回適用し、数値へのキャストに単項プラス+fooを使用し、文字列にキャストするために空の文字列''+fooを連結するのと同様にブール型にキャストするために使用されます。

これらのハックの代わりに、プリミティブ型に対応するコンストラクタ関数( なし newname__を使用せず)を使用して、明示的に値をキャストすることもできます。

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

作業の半分を行う多くの答え。はい、!!Xは「Xの真実性[ブール値として表される]」と読むことができます。しかし、実際には、!!は、単一の変数が真実であるか(または多くの変数であるとしても)偽りであるかどうかを判断するのに重要ではありません。 !!myVar === trueは、単にmyVarと同じです。 !!Xを「実際の」ブール値と比較することは、あまり役に立ちません。

!!で得られるのは、複数の変数の真実性を相互に繰り返し可能かつ標準化された(そしてJSLintフレンドリーな)方法でチェックできることです。

単にキャスト:(

あれは...

  • 0 === falsefalseです。
  • !!0 === falsetrueです。

上記はあまり役に立ちません。 if (!0)は、if (!!0 === false)と同じ結果を提供します。変数をブール値にキャストしてから「真の」ブール値と比較する良いケースは考えられません。

JSLintの指示 から「==および!=」を参照してください(注:Crockfordはサイトを少し動かしています。リンクはある時点で死にそうです)。

==および!=演算子は、比較する前に型強制を行います。 '\ t\r\n' == 0が真になるため、これは悪いです。これにより、タイプエラーをマスクできます。 JSLintは、==が正しく使用されているかどうかを確実に判別できないため、==および!=をまったく使用せず、常により信頼性の高い===および!==演算子を常に使用することをお勧めします。

値が真実または偽であることだけを気にする場合は、短い形式を使用します。の代わりに
(foo != 0)

言うだけ
(foo)

代わりに
(foo == 0)

いう
(!foo)

ブール値を数値と比較するときに、ブール値が数値にキャストされる(true1およびfalse0にキャストされる) 直感的でないケース があることに注意してください。この場合、!!が精神的に役立つ場合があります。ただし、これらは、非ブール値をハードタイプのブール値と比較している場合です。つまり、重大な間違いです。if (-1)はまだここに行く方法です。

╔═══════════════════════════════════════╦═══════════════════╦═══════════╗
║               Original                ║    Equivalent     ║  Result   ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1 == true) console.log("spam")   ║ if (-1 == 1)      ║ undefined ║
║ if (-1 == false) console.log("spam")  ║ if (-1 == 0)      ║ undefined ║
║   Order doesn't matter...             ║                   ║           ║
║ if (true == -1) console.log("spam")   ║ if (1 == -1)      ║ undefined ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (!!-1 == true) console.log("spam") ║ if (true == true) ║ spam      ║ better
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1) console.log("spam")           ║ if (truthy)       ║ spam      ║ still best
╚═══════════════════════════════════════╩═══════════════════╩═══════════╝

そして、エンジンによっては物事がさらに狂気になります。たとえば、WScriptが賞を受賞しました。

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

いくつかの歴史的なWindows jive のため、メッセージボックスに-1を出力します! cmd.exeプロンプトで試してみてください!ただし、WScript.echo(-1 == test())は0またはWScriptのfalseのままです。 見てください。恐ろしいです。

真実性の比較:)

しかし、2つの値がある場合、真理/虚偽が等しいかどうかを確認する必要がありますか?

myVar1 = 0;myVar2 = undefined;があるとします。

  • myVar1 === myVar20 === undefinedであり、明らかにfalseです。
  • !!myVar1 === !!myVar2!!0 === !!undefinedであり、本当です!同じ真実! (この場合、両方とも「偽りの真実」を持っています。)

したがって、「ブールキャスト変数」を本当に使用する必要がある唯一の場所は、両方の変数がsameの真実性を持っているかどうかを確認する状況がある場合です。あれは、 2つの変数が両方とも真実であるか、両方が偽(またはそうでない)、つまり等しい(またはない)かどうかを確認する必要がある場合は、!!を使用します真実性

私はそのオフハンドのための素晴らしい、考案されていないユースケースを考えることはできません。フォームに「リンク」フィールドがあるのでしょうか?

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月19日編集:

明示的なブール値を期待するサードパーティのライブラリ

ここに興味深いケースがあります... !!は、サードパーティのライブラリが明示的なブール値を期待している場合に便利です。

たとえば、 JSX(React)のFalseは特別な意味を持ちます これは単純な偽造ではトリガーされませんJSXで次のようなものを返そうとした場合、messageCount...

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

...メッセージが0個のときにReactが0をレンダリングするのに驚くかもしれません。 JSXがレンダリングされないようにするには、明示的にfalseを返す必要があります。上記のステートメントは、0を返します。これは、JSXが適切にレンダリングするものです。 Count: {messageCount && <div>Get your count to zero!</div>}(またはより不自然なもの)を持っていなかったことはわかりません。

  • 1つの修正には、0falseである!!0に強制するbangbangが含まれます。
    {!!messageCount && <div>You have messages!</div>}

  • JSXのドキュメントでは、より明示的になり、自己コメントコードを記述し、比較を使用してブール値に強制することを推奨しています。
    {messageCount > 0 && <div>You have messages!</div>}

  • 虚偽を自分で3項で処理する方が快適です-
    {messageCount ? <div>You have messages!</div> : false}

TypeScriptでも同様です。ブール値を返す関数がある場合(またはブール変数に値を割り当てている場合)、[通常]ブール値を返す/割り当てることはできません。厳密に型指定されたブール値である必要があります。つまり、myObjectが厳密に型指定されている場合return !myObject;はブール値を返す関数では機能しますが、return myObject;では機能しません。 TypeScriptの期待に合わせてreturn !!myObjectする必要があります。

Typescriptの例外? myObjectanyだった場合、戻り値の型がブール値であっても、JavaScriptのWild Westに戻り、!!なしで返すことができます。

これらはJSXおよびTypeScriptの規則であり、JavaScript固有のものではないことに注意してください

しかし、レンダリングされたJSXに奇妙な0sが表示される場合、ゆるい偽の管理を考えてください。

62
ruffin

これは単なる論理NOT演算子で、2回です。何かをブール値に変換するために使用されます。

true === !!10

false === !!0
50
Greg

接尾辞をブール値に変換します。 

30
Paul McMillan

これは二重のnot操作です。最初の!は値をブール値に変換し、その論理値を反転します。 2番目の!は論理値を反転します。

24
Bill the Lizard

Boolean()キャスト関数の動作をシミュレートします。最初のNOTは、与えられたオペランドに関係なくブール値を返します。 2番目のNOTは、そのBoolean値を否定するので、変数のtrueブール値を与えます。最終結果は、値にBoolean()関数を使用するのと同じです。

22
Prakash

!!演算子は二重否定になるようです。

var foo = "Hello World!";

!foo // Result: false
!!foo // Result: true
21
Steve Harrison

!これは基本的に "enable"の値をその逆の真偽値に型キャストします。二番目 !この値を反転します。したがって、!!enableは「有効にしない」という意味で、enableの値をブール値として使用します。

18

言及する価値があるのは、論理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
17
GreQ

!!構文は、JavaScriptの式をに変換する簡単な方法です。 

例えば、!!"he shot me down" === true!!0 === falseです。

14
Navin Rauniyar

それは一人の演算子ではなく、二人の演算子です。これは以下と同等で、値をブール値にキャストする簡単な方法です。 

val.enabled = !(!enable);
11
Justin Johnson

!!NOT操作を一緒に2回使っています、!は値をbooleanに変換して逆にします。これは!!がどのように機能するかを見る簡単な例です:

最初に、あなたが持っている場所:

var zero = 0;

その後、!0を実行します。0はtrueであるため、ブール値に変換されてfalsyに評価されます。したがって、逆の値を取得してブール値に変換されるので、trueに評価されます。

!zero; //true

しかし、値の反転されたブール値を使用したくないので、結果を取得するために再度値を反転させることができます。だからこそ私たちは別の!を使用しています。

基本的に、!!は私たちが確かめることを確実にします、我々が得る値はブール値で、偽造、真実、文字列などではありません...

つまり、JavaScriptでBoolean関数を使用するのと同じですが、値をブール値に変換する簡単で短い方法です。

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

ifおよびwhileステートメントと?演算子は、実行するコードの分岐を決定するために真理値を使用します。たとえば、ゼロとNaNの数字および空の文字列はfalseですが、他の数字と文字列はtrueです。オブジェクトは真ですが、未定義の値とnullは両方とも偽です。

二重否定演算子!!は、値の真理値を計算します。実際には2つの演算子です。ここで、!!x!(!x)を意味し、次のように動作します。

  • xがfalse値の場合、!xtrue!!xfalseです。
  • xが真の値の場合、!xfalse!!xtrueです。

ブール値コンテキストの最上位レベル(ifwhile、または?)で使用した場合、!!演算子は動作上何もしません。たとえば、if (x)if (!!x)は同じ意味です。

実用的な使い方

しかし、それはいくつかの実用的な用途があります。

1つの用途は、オブジェクトをその真理値に非可逆圧縮して、コードが大きなオブジェクトへの参照を保持していないようにすることです。 !!some_big_objectの代わりにsome_big_objectを変数に代入することは、ガベージコレクタのためにそれを捨て去ります。これは、オブジェクト、またはnullなどの偽の値、またはブラウザ機能の検出などの未定義の値を生成する場合に役立ちます。

私が Cの対応する!!演算子についての回答 で言及したもう一つの用途は、一般的なタイプミスや印刷診断を探す "lint"ツールです。たとえば、CとJavaScriptの両方で、ブール演算の一般的ないくつかの誤字は、出力がブールではない他の動作を生成します。

  • if (a = b)は代入の後にbの真理値を使います。 if (a == b)は等価比較です。
  • if (a & b)はビットごとのANDです。 if (a && b)は論理積です。 2 & 50(false値)です。 2 && 5は真実です。

!!演算子は、あなたが書いたものがあなたが意図したものであることをlintツールに安心させます:この操作をしてから、結果の真理値を取ります。

3番目の用途は、論理XORと論理XNORを生成することです。 CとJavaScriptの両方で、a && bは論理積(両側が真の場合は真)を実行し、a & bはビット単位の論理積を実行します。 a || bは論理ORを実行し(少なくとも1つが真の場合はtrue)、a | bはビットごとのORを実行します。 a ^ bにはビットごとのXOR(排他的論理和)がありますが、論理的なXORの組み込み演算子はありません(片側が真ならば真)。たとえば、ユーザーが2つのフィールドのうちの1つにテキストを入力できるようにしたい場合があります。あなたができることはそれぞれ真理値に変換してそれらを比較することです:!!x !== !!y

8
Damian Yerrick

私はこれがC + +から人々が上書きする残り物だと思う!ブール演算子ではありません。

したがって、その場合に否定的(または肯定的)な答えを得るには、まず!を使用する必要があります。ブール値を取得する演算子ですが、肯定的なケースをチェックしたい場合は!!を使用します。

8
Darren Clark

二重ブール否定。値が未定義でないかどうかを確認するためによく使用されます。

7
Sergey Ilinsky

!!xBoolean(x)の省略形です。

最初の強打はjsエンジンにBoolean(x)を実行させますが、値を反転するという副作用もあります。だから第二の強打は副作用を元に戻します。

7
Greg Gum

ここにはたくさんの素晴らしい答えがありますが、ここまで読んだことがあるなら、これは私が「それを得る」のに役立ちました。 Chromeなどでコンソールを開き、次のように入力します。

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

当然のことながら、これらは単に!! someThingと入力するのと同じですが、括弧を追加すると理解しやすくなります。

7
Warren Davis

それはすべてを真偽値にします。 

例えば:

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); // -> undefined
console.log(!0 === false); // -> false
console.log(!!0 === false); // -> true
5
Khuong

これは角度jsからのコードの一部です 

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になり、もう1つ!それは本当だろう

requestAnimationFrameが未定義に割り当てられている場合、!requestAnimationFrameは真になり、もう1つ!それは間違っているだろう

変数のブール値を返します。

代わりにBooleanクラスを使うことができます。

(コードの説明を読んでください)

var X = "test"; // X value is "test" as a String value
var booleanX = !!X // booleanX is `true` as a Boolean value beacuse 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 to `!!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

3
efkan

私はちょうどそれを追加したかった

if(variableThing){
  // do something
}

と同じです

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

しかし、何かが未定義の場合、これは問題になる可能性があります。

// a is undefined, b is empty object.
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

ここでのトリックは&&sの連鎖であり、最初のfalsey値が返されます - そしてこれはif文などに渡されます。 b.foo.bar文を実行してもエラーになりません。

上記はundefinedを返しますが、空の文字列、false、null、0、undefinedがある場合、それらの値が返され、チェーンでそれらが見つかるとすぐに[]{}はどちらも真実です。

3
Ryan Taylor

JavaScriptの中には暗黙の型変換を行うものがあり、型変換のために使用されることがあります。

単項!演算子は、そのオペランドをブール値に変換してそれを否定します。

この事実は、あなたがあなたのソースコードで見ることができるという次のイディオムにつながります:

!!x // Same as Boolean(x). Note double exclamation mark
3
GibboK

!!は、 Boolean constructor を使用することに似ています。または、ほぼ間違いなく ブール関数。

console.log(Boolean(null)); // Preffered over the Boolean object

console.log(new Boolean(null).valueOf()); // Not recommended for coverting non-boolean values

console.log(!!null); // A hacky way to omit calling the Boolean function, but essentially does the same thing. 


// The context you saw earlier (your example)
var vertical;

function Example(vertical)
{
        this.vertical = vertical !== undefined ? !!vertical : 
        this.vertical; 
        // Let's break it down: If vertical is strictly not undefined, return the boolean value of vertical and set it to this.vertical. If not, don't set a value for this.vertical (just ignore it and set it back to what it was before; in this case, nothing).   

        return this.vertical;
}

console.log( "\n---------------------" )

// vertical is currently undefined

console.log(new Example(vertical).vertical); // The falsey or truthy value of this.vertical
console.log(!!new Example(vertical).vertical); // Coerced value of this.vertical

vertical = 12.5; // set vertical to 12.5, a truthy value.
console.log(new Example(vertical).vertical); // The falsey or truthy value of this.vertical which happens to be true anyway
console.log(!!new Example(vertical).vertical); // Coerced value of this.vertical

vertical = -0; // set vertical to -0, a falsey value.
console.log(new Example(vertical).vertical); // The falsey or truthy value of this.vertical which happens to be false either way
console.log(!!new Example(vertical).vertical); // Coerced value of this.vertical

Falsey値 in JavaScriptcoerceto false 、および truthy values coerceto true. falsey and truthy values can ifステートメントでも使用され、対応するブール値に基本的に「マッピング」されます。ただし、出力(戻り値)の大部分が異なるため、適切なブール値を頻繁に使用する必要はないでしょう。

これはキャストに似ているように見えるかもしれませんが、現実的には単なる偶然であり、ブールキャスト用に「構築」されたり、意図的に作成されたりしません。だからそれを呼ばないようにしましょう。


理由と仕組み

簡潔にするために、! ( !null )のようになります。一方、nullfalseyなので、!nulltrue。次に、!truefalseになり、本質的に invert back になりますが、今回は適切なブール値(またはその逆真の値{}または1など) 。


あなたの例に戻って

全体的に、あなたが見たコンテキストは、verticalが定義されているかどうかに応じて、単にthis.verticalを調整します。結果の垂直のブール値に設定されます。それ以外の場合は変更されません。つまり、verticalが定義されている場合、 this.verticalはそのブール値に設定されますが、そうでない場合は同じままです。それ自体が!!の使用方法とその機能の例だと思います。


垂直I/Oの例

この例を実行し、入力の垂直値をいじります。コンテキストのコードを完全に理解できるように、結果の強制対象を確認します。入力に、有効なjavascript値を入力します。 文字列をテストする場合は、引用符を含めることを忘れないでください。CSSとHTMLコードをあまり気にしないでください。このスニペットを実行して遊んでください。それと。ただし、DOMに関連しないJavaScriptコード(例のコンストラクターと垂直変数の使用)を確認することもできます。

var vertical = document.getElementById("vertical");
var p = document.getElementById("result");

function Example(vertical)
{
        this.vertical = vertical !== undefined ? !!vertical : 
        this.vertical;   

        return this.vertical;
}

document.getElementById("run").onclick = function()
{

  p.innerHTML = !!( new Example(eval(vertical.value)).vertical );
  
}
input
{
  text-align: center;
  width: 5em;
} 

button 
{
  margin: 15.5px;
  width: 14em;
  height: 3.4em;
  color: blue;
}

var 
{
  color: purple;
}

p {
  margin: 15px;
}

span.comment {
  color: brown;
}
<!--Vertical I/O Example-->
<h4>Vertical Example</h4>
<code id="code"><var class="var">var</var> vertical = <input type="text" id="vertical" maxlength="9" />; <span class="comment">// enter any valid javascript value</span></code>
<br />
<button id="run">Run</button>
<p id="result">...</p>
2

論理否定演算子を2回使用する
つまり、!true = false
and !! true = true

2
Abhay Dixit

これらすべての素晴らしい答えを見た後、私は!!を使うもう一つの理由を加えたいと思います。現在はAngular 2-4(TypeScript)で作業していますが、ユーザーが認証されていない場合はfalseとしてブール値を返します。認証されていない場合は、token-stringはnullまたは""になります。次のコードブロックを使用してこれを実行できます。

public isAuthenticated(): boolean {
   return !!this.getToken();
}
2
Wouter Vanherck
a = 1;
alert(!a) // -> false : a is not not defined
alert(!!a) // -> true : a is not not defined

!aの場合、aNOT定義されているかどうかをチェックし、!!aは変数が定義されているかどうかをチェックします。

!!a!(!a)と同じです。 aが定義されている場合、atrue!afalse、および!!atrueです。

2
user3698272

この質問はきわめて徹底的に答えられていますが、できるだけ単純化されていることを意味する答えを追加したいと思います。できるだけ簡単に把握することができます。

Javascriptには "truthy"および "falsey"値と呼ばれるものがあるため、他の式で評価されると、検査対象の値または式が実際にはtrueまたはfalseでなくても、trueまたはfalseの条件になる式があります。

例えば:

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

その要素が実際に存在する場合、式はtrueと評価され、コードブロックが実行されます。

しかしながら:

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

...は真の状態にはならず、要素が存在していてもコードブロックは実行されません。

どうして?なぜなら、document.getElementById()はこのif()ステートメントで真と評価される "真実"の式だからですが、実際のブール値であるtrueではありません。

この場合の二重の "not"はとても単純です。これは単純に2つのnotが連続しているだけです。

最初のものは単純に真偽値または偽の値を「反転」して実際のブール型になり、次に2番目のものは元の状態に戻りますが、現在は実際のブール値になります。そのようにあなたは一貫性を持っています:

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

そして

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

予想どおり、両方がtrueを返します。

1
Klw Wallace

二重変数をブール値に評価します。例:false 0(ゼロ)、 ''、または ""(空の文字列)、null、未定義、NaNはfalseと評価されます。この投稿を参照 https://www.sitepoint .com/javascript-truthy-falsy/

0
tolotrasmile