このJavaScriptのスニペットを考えると...
var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';
var f = a || b || c || d || e;
alert(f); // 4
誰かがこのテクニックが何であるか私に説明してもらえますか(私の最もよい推測はこの質問のタイトルにあります!)?そしてそれはどのように/なぜそれは正確に動作しますか?
私の理解するところでは、変数f
はnullでも未定義でもない値を持つ最初の変数の(左から右への)最も近い値に代入されるということです。それがたくさん使われるのを見ました。
また、この手法はJavaScriptに固有のものですか? PHPで同様のことをすると、f
の値自体ではなく、d
のブール値が真になることがわかっています。
説明は 短絡評価 を参照してください。これはこれらの演算子を実装する一般的な方法です。 JavaScriptに固有のものではありません。
これは、デフォルト値を代入するために作られています。この場合、y
変数がfalsyの場合はx
の値です。 .
JavaScriptのブール演算子はオペランドを返すことがありますが、他の言語のように常にブール結果になるとは限りません。
Logical OR演算子(||
)は、最初のオペランドが偽の場合は2番目のオペランドの値を返し、それ以外の場合は最初のオペランドの値を返します。
例えば:
"foo" || "bar"; // returns "foo"
false || "bar"; // returns "bar"
Falsy値は、ブール値のコンテキストで使用するとfalse
に強制される値で、0
、null
、undefined
、空の文字列、NaN
、そしてもちろんfalse
です。 。
Javacriptは、論理演算子||
および&&
に 短絡評価 を使用します。 ただし、true
またはfalse
の値の代わりに、実行を停止した最後の値の結果を返すという点で他の言語とは異なります。
次の値は、JavaScriptでは偽と見なされます。
""
(空の文字列)演算子の優先順位 ルールを無視し、物事をシンプルに保つために、次の例はどの値が評価を停止し、結果として返されるかを示しています。
false || null || "" || 0 || NaN || "Hello" || undefined // "Hello"
NaN
までの最初の5つの値は偽であるため、最初の真理値-"Hello"
に達するまですべて左から右に評価され、式全体が真になるため、それ以上は評価されません。 、および"Hello"
は式の結果として返されます。同様に、この場合:
1 && [] && {} && true && "World" && null && 2010 // null
最初の5つの値はすべて真実であり、最初の偽の値(null
)に達するまで評価され、式が偽になるため、2010
は評価されなくなり、null
が返されます式の結果として。
指定した例は、JavaScriptのこのプロパティを使用して割り当てを実行しています。値のセットの中で最初の真の値または偽の値を取得する必要がある場所であればどこでも使用できます。以下のこのコードは、if-elseチェックを行う代わりに、デフォルト値を割り当てやすくするため、値"Hello"
をb
に割り当てます。
var a = false;
var b = a || "Hello";
以下の例をこの機能の活用と呼ぶことができますが、コードが読みにくくなると思います。
var messages = 0;
var newMessagesText = "You have " + messages + " messages.";
var noNewMessagesText = "Sorry, you have no new messages.";
alert((messages && newMessagesText) || noNewMessagesText);
アラート内で、messages
が偽であるかどうかを確認し、偽の場合はnoNewMessagesText
を評価して返し、それ以外の場合はnewMessagesText
を評価して返します。この例では偽であるため、noNewMessagesTextで停止し、"Sorry, you have no new messages."
をアラートします。
JavaScript変数は型指定されていないので、fにはブール演算子を介して割り当てられていても整数値を割り当てることができます。
fに最も近い値が割り当てられ、falseと同義ではありません。そのため、0、false、null、undefinedがすべて渡されます。
alert(null || undefined || false || '' || 0 || 4 || 'bar'); // alerts '4'
それに対する魔法はありません。 a || b || c || d
のようなブール式は遅延評価されます。 Interpeterはa
の値を検索し、未定義なのでfalseに進みます。次にnullであるb
が表示されますが、まだfalseの結果が表示されます。その後、c
が表示されます。最後に、それはd
を見て、「ハァッ、それはnullではないので、私の結果が得られます」と言って、それを最後の変数に割り当てます。
このトリックは、ブール式の遅延短絡評価を行うすべての動的言語で機能します。静的言語ではコンパイルされません(型エラー)。ブール式の評価に熱心な言語では、論理値を返します(つまり、この場合はtrue)。
この質問はすでにいくつかの良い答えを受けています。
まとめると、この手法は、言語のコンパイル方法の機能を利用しています。つまり、JavaScriptはブール演算子の評価を「短絡」し、最初の偽ではない変数値、または最後の変数に含まれるものに関連付けられた値を返します。偽と評価される値についてのAnuragの説明を参照してください。
このテクニックを使用することは、いくつかの理由から良い習慣ではありません。しかしながら。
文書化された機能:このニーズを満たし、さらに多くの言語で一貫している既存の代替手段があります。これは三項演算子になります。
()?値1:値2.
3項演算子を使用すると、もう少し入力が必要ですが、評価されているブール式と割り当てられている値が明確に区別されます。さらにそれを連鎖させることができるので、上記で実行されているデフォルト割り当てのタイプを再現することができます。
var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';
var f = ( a ) ? a :
( b ) ? b :
( c ) ? c :
( d ) ? d :
e;
alert(f); // 4
出力の最初の真の値を返します。
すべてがfalseの場合、最後のfalse値を返します。
例: -
null || undefined || false || 0 || 'Apple' // Return Apple
新しい変数(z
)を、 "truthy"の場合はx
の値(ゼロ以外、有効なオブジェクト/配列/関数/その他)、またはそれ以外の場合はy
に設定します。 x
が存在しない場合にデフォルト値を提供する比較的一般的な方法です。
たとえば、オプションのコールバックパラメータを取る関数がある場合は、何もしないデフォルトのコールバックを指定できます。
function doSomething(data, callback) {
callback = callback || function() {};
// do stuff with data
callback(); // callback will always exist
}
そのショートサーキットオペレータ。
短絡評価では、2番目の引数は、最初の引数が式の値を決定するのに十分でない場合にのみ実行または評価されます。 OR(||)関数の最初の引数がtrueと評価された場合、全体の値はtrueでなければなりません。
関数の引数にデフォルト値を設定するためにも使用できます。
function theSameOldFoo(name){
name = name || 'Bar' ;
console.log("My best friend's name is " + name);
}
theSameOldFoo(); // My best friend's name is Bar
theSameOldFoo('Bhaskar'); // My best friend's name is Bhaskar`
x
が設定されている場合、z
の値はx
になります。それ以外の場合、y
が設定されている場合、その値はz
の値として設定されます。
それはと同じです
if(x)
z = x;
else
z = y;
JavaScriptの論理演算子はブール値を返さないが、操作を完了するのに必要な最後の要素の値(OR文では、AND文では最初の偽でない値になる)それは最後のものでしょう)。操作が失敗すると、false
が返されます。
Xを評価し、Xがnull、空の文字列、または0(論理的に偽)でない場合、それをzに割り当てます。 Xがnull、空の文字列、または0(論理値false)の場合、zにyが割り当てられます。
var x = '';
var y = 'bob';
var z = x || y;
alert(z);
'bob'を出力します。
Bill Higginsのブログの投稿によると。 Javascriptの論理OR代入慣用句 (2007年2月)、この振る舞いはv1.2(少なくとも)現在のものです
彼はまたそれのための別の使用法(引用)を提案している。「ブラウザ間の違いの軽量正規化」
// determine upon which element a Javascript event (e) occurred
var target = /*w3c*/ e.target || /*IE*/ e.srcElement;