web-dev-qa-db-ja.com

JavaScript OR(||)変数代入説明

この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のブール値が真になることがわかっています。

315
chattsm

説明は 短絡評価 を参照してください。これはこれらの演算子を実装する一般的な方法です。 JavaScriptに固有のものではありません。

196
unwind

これは、デフォルト値を代入するために作られています。この場合、y変数がfalsyの場合はxの値です。 .

JavaScriptのブール演算子はオペランドを返すことがありますが、他の言語のように常にブール結果になるとは限りません。

Logical OR演算子(||)は、最初のオペランドが偽の場合は2番目のオペランドの値を返し、それ以外の場合は最初のオペランドの値を返します。

例えば:

"foo" || "bar"; // returns "foo"
false || "bar"; // returns "bar"

Falsy値は、ブール値のコンテキストで使用するとfalseに強制される値で、0nullundefined、空の文字列、NaN、そしてもちろんfalseです。 。

169
CMS

Javacriptは、論理演算子||および&&短絡評価 を使用します。 ただし、trueまたはfalseの値の代わりに、実行を停止した最後の値の結果を返すという点で他の言語とは異なります。

次の値は、JavaScriptでは偽と見なされます。

  • false
  • ヌル
  • ""(空の文字列)
  • ナン
  • undefined

演算子の優先順位 ルールを無視し、物事をシンプルに保つために、次の例はどの値が評価を停止し、結果として返されるかを示しています。

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."をアラートします。

153
Anurag

JavaScript変数は型指定されていないので、fにはブール演算子を介して割り当てられていても整数値を割り当てることができます。

fに最も近い値が割り当てられ、falseと同義ではありません。そのため、0、false、null、undefinedがすべて渡されます。

alert(null || undefined || false || '' || 0 || 4 || 'bar'); // alerts '4'
45
Alsciende

それに対する魔法はありません。 a || b || c || dのようなブール式は遅延評価されます。 Interpeterはaの値を検索し、未定義な​​のでfalseに進みます。次にnullであるbが表示されますが、まだfalseの結果が表示されます。その後、cが表示されます。最後に、それはdを見て、「ハァッ、それはnullではないので、私の結果が得られます」と言って、それを最後の変数に割り当てます。

このトリックは、ブール式の遅延短絡評価を行うすべての動的言語で機能します。静的言語ではコンパイルされません(型エラー)。ブール式の評価に熱心な言語では、論理値を返します(つまり、この場合はtrue)。

29
Marcin

この質問はすでにいくつかの良い答えを受けています。

まとめると、この手法は、言語のコンパイル方法の機能を利用しています。つまり、JavaScriptはブール演算子の評価を「短絡」し、最初の偽ではない変数値、または最後の変数に含まれるものに関連付けられた値を返します。偽と評価される値についてのAnuragの説明を参照してください。

このテクニックを使用することは、いくつかの理由から良い習慣ではありません。しかしながら。

  1. コードの読みやすさ:これはブール演算子を使用しており、これのコンパイル方法の動作が理解されていない場合、期待される結果はブール値になります。
  2. 安定性:これは、複数の言語間で矛盾する言語のコンパイル方法の機能を使用しているため、将来的に変更の対象になる可能性があります。
  3. 文書化された機能:このニーズを満たし、さらに多くの言語で一貫している既存の代替手段があります。これは三項演算子になります。

    ()?値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
9
WSimpson

出力の最初の真の値を返します。

すべてがfalseの場合、最後のfalse値を返します。

例: -

  null || undefined || false || 0 || 'Apple'  // Return Apple
5
Arshid KV

新しい変数(z)を、 "truthy"の場合はxの値(ゼロ以外、有効なオブジェクト/配列/関数/その他)、またはそれ以外の場合はyに設定します。 xが存在しない場合にデフォルト値を提供する比較的一般的な方法です。

たとえば、オプションのコールバックパラメータを取る関数がある場合は、何もしないデフォルトのコールバックを指定できます。

function doSomething(data, callback) {
    callback = callback || function() {};
    // do stuff with data
    callback(); // callback will always exist
}
4
Matthew Crumley

そのショートサーキットオペレータ。

短絡評価では、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`
1
Vijay

xが設定されている場合、zの値はxになります。それ以外の場合、yが設定されている場合、その値はzの値として設定されます。

それはと同じです

if(x)
  z = x;
else
  z = y;

JavaScriptの論理演算子はブール値を返さないが、操作を完了するのに必要な最後の要素の値(OR文では、AND文では最初の偽でない値になる)それは最後のものでしょう)。操作が失敗すると、falseが返されます。

1
Andris

Xを評価し、Xがnull、空の文字列、または0(論理的に偽)でない場合、それをzに割り当てます。 Xがnull、空の文字列、または0(論理値false)の場合、zにyが割り当てられます。

var x = '';
var y = 'bob';
var z = x || y;
alert(z);

'bob'を出力します。

0
tvanfosson

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;
0
Alon Brontman