!function () {}();
!function () {}();
回答:
JavaScript構文101。これは関数宣言です。
function foo() {}
セミコロンがないことに注意してください。これは単なる関数宣言です。foo()
関数を実際に実行するには、呼び出しが必要です。
ここで、一見無害な感嘆符を追加!function foo() {}
すると、式に変わります。これは関数式になりました。
!
単体はもちろん、機能呼び出しませんが、私たちは今置くことができます()
最後に:!function foo() {}()
より高い優先順位を持つ!
とすぐに関数を呼び出します。
したがって、作成者が行っているのは、関数式ごとに1バイトを節約することです。それを書くためのより読みやすい方法はこれでしょう:
(function(){})();
最後に!
、式をtrueに戻します。これは、デフォルトですべての生命維持のリターンであるundefined
と私たちを残し、!undefined
ですtrue
。特に役に立たない。
!
ブール値を返しますが、誰もが知っていることですが、関数宣言ステートメントを関数式に変換するので、括弧で囲まずに関数をすぐに呼び出すことができます。明白ではない、そして明らかにコーダーの意図。
var foo =
はステートメント/式のあいまいさを解消し、単純にvar foo = function(bar){}("baz");
等を書くことができます
関数:
function () {}
何も返しません(または未定義)。
作成した関数をすぐに呼び出したい場合があります。あなたはこれを試してみたくなるかもしれません:
function () {}()
しかし、結果はになりSyntaxError
ます。
!
関数の前に演算子を使用すると、式として扱われるため、次のように呼び出すことができます。
!function () {}()
これは、関数の戻り値の反対のブール値(この場合は)も返すtrue
ため!undefined
ですtrue
。実際の戻り値を呼び出しの結果にしたい場合は、次のようにしてみてください。
(function () {})()
!
関数宣言を関数式に変換することです、それだけです。
!function
構文を使用します
!
マークされた関数呼び出しに使用するのに良い点がありますairbnb JavaScriptガイドでます
一般に、後で連結される個別のファイル(モジュール)でこの手法を使用するためのアイデア。ここでの注意点は、新しいファイルを新しい行に配置するツールによってファイルが連結されることになっていることです(とにかく、ほとんどの連結ツールの一般的な動作です)。その場合、!
以前に連結されたモジュールが末尾のセミコロンを逃した場合にエラーを回避するのに役立ちますが、心配せずにそれらを任意の順序で配置できる柔軟性が得られます。
!function abc(){}();
!function bca(){}();
と同じように機能します
!function abc(){}();
(function bca(){})();
1つの文字を保存し、任意の見栄えが良くなります。
そして、方法のいずれかによって+
、-
、~
、void
あなたは彼らが異なる動作をすることを関数から返すために何かを使用する必要がある場合、オペレータは確かに、機能を呼び出すという点で、同じ効果を持っています。
abcval = !function abc(){return true;}() // abcval equals false
bcaval = +function bca(){return true;}() // bcaval equals 1
zyxval = -function zyx(){return true;}() // zyxval equals -1
xyzval = ~function xyz(){return true;}() // your guess?
しかし、1ファイル1モジュールのコード分離にIIFEパターンを使用し、最適化のために連結ツールを使用する場合(1行1ファイルのジョブになります)、構築
!function abc(/*no returns*/) {}()
+function bca() {/*no returns*/}()
最初のコードサンプルと同じように、安全なコード実行を行います。
これはエラーをスローし、JavaScript ASIはその作業を実行できなくなります。
!function abc(/*no returns*/) {}()
(function bca() {/*no returns*/})()
単項演算子に関する1つの注意事項は、それらは同様の作業を行うことになりますが、場合にのみ、最初のモジュールでは使用されませんでした。したがって、連結順序を完全に制御できなければ、安全ではありません。
これは機能します:
!function abc(/*no returns*/) {}()
^function bca() {/*no returns*/}()
これは:
^function abc(/*no returns*/) {}()
!function bca() {/*no returns*/}()
ステートメントがfalseと評価できるかどうかを返します。例えば:
!false // true
!true // false
!isValid() // is not valid
これを2回使用して、値をブール値に強制できます。
!!1 // true
!!0 // false
だから、あなたの質問にもっと直接答えるには:
var myVar = !function(){ return false; }(); // myVar contains true
編集:関数宣言を関数式に変更するという副作用があります。たとえば、次のコードは、必要な識別子(または関数名)がない関数宣言として解釈されるため、無効です。
function () { return false; }(); // syntax error
var myVar = !function(){ return false; }()
は!
同様のものvar myVar = function(){ return false; }()
を省略でき、関数は正しく実行され、戻り値は変更されません。
true
と!0
してfalse
と!1
。2文字または3文字節約できます。
これは、JavaScriptの縮小化を行うときにデータのバイトを保存するだけです。
以下の無名関数を考えます
function (){}
上記を自己呼び出し関数として作成するには、通常、上記のコードを次のように変更します。
(function (){}())
ここで、関数を呼び出すために必要な、関数の最後に(,)
追加すること()
を除いて、2つの文字を追加しました。縮小のプロセスでは、通常、ファイルサイズを小さくすることに重点を置きます。したがって、上記の関数を次のように書くこともできます
!function (){}()
それでも、どちらも自己呼び出し関数であり、バイトも保存します。2文字で(,)
はなく1文字を使用しました!
!論理否定です演算子です。ブール演算子であり、何かをその逆に反転させます。
関数の前にBANG(!)を使用することにより、呼び出された関数の括弧をバイパスすることができますが、それでも戻り値は反転されます。IEFEの場合と同様に、undefinedが返され、反転するとブール値のtrueになります。
代わりに、必要に応じて閉じ括弧とBANG(!)を使用してください。
// I'm going to leave the closing () in all examples as invoking the function with just ! and () takes away from what's happening.
(function(){ return false; }());
=> false
!(function(){ return false; }());
=> true
!!(function(){ return false; }());
=> false
!!!(function(){ return false; }());
=> true
働く他のオペレーター...
+(function(){ return false; }());
=> 0
-(function(){ return false; }());
=> -0
~(function(){ return false; }());
=> -1
結合演算子...
+!(function(){ return false; }());
=> 1
-!(function(){ return false; }());
=> -1
!+(function(){ return false; }());
=> true
!-(function(){ return false; }());
=> true
~!(function(){ return false; }());
=> -2
~!!(function(){ return false; }());
=> -1
+~(function(){ return false; }());
+> -1
感嘆符は、すべての関数が常にブール値を返すようにします。
最終値は、関数によって返された値の否定です。
!function bool() { return false; }() // true
!function bool() { return true; }() // false
!
上記の例を省略すると、SyntaxErrorになります。
function bool() { return true; }() // SyntaxError
ただし、これを実現するより良い方法は次のとおりです。
(function bool() { return true; })() // true
!
ランタイムが関数を解析する方法を変更します。これにより、ランタイムは関数を(宣言ではなく)関数式として扱います。これにより、開発者は()
構文を使用して関数をすぐに呼び出すことができます。!
関数式を呼び出した結果にもそれ自体を適用(つまり否定)します。
!
結果としてあなたが期待しているものは何でも否定します(反対です)
var boy = true;
undefined
boy
true
!boy
false
あなたが呼ぶときboy
、あなたの結果になりますtrue
が、あなたが追加した瞬間は!
呼び出すときboy
、すなわち!boy
、あなたの結果になりますfalse
。これはつまり、あなたが意味NotBoyを、それは基本的にはboolean型の結果だ。この時、いずれかtrue
またはfalse
。
これは!function () {}();
式に起こるのと同じことであり、実行function () {}();
するとエラーのフラグが立てられるだけです!
が、function () {}();
式の直前に追加すると、function () {}();
が返すはずのの反対になりますtrue
。以下に例を示します。
function () {}();
SyntaxError: function statement requires a name
!function () {}();
true