論理積と論理和で代入する値を選択する

あるスクリプトを見ていたら、


obj = obj0 && obj1 || obj2;
if(obj.prp)//obj.prpがtrueの場合の処理

みたいな書き方をしていて、「何だ、こりゃ?」と思った。 ひょっとして、「if(obj0 && obj1 && obj2)みたいに展開されるんだろうか?」とも思ったが、 ドット演算子(.)の意味とか考えてもそれはおかしいと思って、 ECMAスクリプトの仕様書の邦訳を見てみたら、 このような注釈があった。

&& 演算子、また || 演算子の生成する値が Boolean 型である必要はない。 生成される値は常に、 2 個の項式のうちの 1 つの値である。

結局こうなるということらしい。

値1&&値2
値1がfalseなら値1が評価される。値1がtrueなら値2が評価される。
値1||値2
値1がtrueなら値1が評価される。値1がfalseなら値2が評価される。

ということは、論理積と論理和を用いて、変数に代入するオブジェクトを選択していたということか!

というわけで、早速実験。


<script type="text/javascript">
a=0;
b=1;
c=2;
d=0;
e="";
f="ほげ";
g="あべし";
h="ひでぶ";
var i;		//undefined

r0=a&&b;		//aが0なのでaが代入される
alert(r0);
r1=b&&a;		//bが1なのでaが代入される
alert(r1);
r2=b&&c;		//c
alert(r2);
r3=c&&b;		//b
alert(r3);
r4=a&&d;		//a
alert(r4);


r5=a||b;		//aが0なのでbが代入される
alert(r5);
r6=b||a;		//bが1なのでbが代入される
alert(r6);
r7=b||c;		//b
alert(r7);
r8=c||b;		//c
alert(r8);
r9=a||d;		//d
alert(r9);


r10=e&&f;		//
alert(r10);
r11=f&&e;		//
alert(r11);
r12=f&&g;		//あべし
alert(r12);
r13=g&&f;		//ほげ
alert(r13);


r14=e||f;		//ほげ
alert(r14);
r15=f||e;		//ほげ
alert(r15);
r16=f||g;		//ほげ
alert(r16);
r17=g||f;		//あべし
alert(r17);


r18=i&&a;		//i
alert(r18);
r19=a&&i;		//a
alert(r19);


r20=i||b;		//b
alert(r20);
r21=b||i;		//b
alert(r21);
r22=h||i;		//ひでぶ
alert(r22);


r23=b&&c&&f;		//ほげ。全部trueなら最後の値が入る
alert(r23);


r24=b&&a&&e;		//a。最初にfalseになった値が入る。
alert(r24);
r25=b&&i&&a;		//i
alert(r25);


r26=a||d||f;		//ほげ。最初にtrueになった値が入る。
alert(r26);
r27=a||g||h;		//あべし。
alert(r27);
r28=h||b||f;		//ひでぶ。
alert(r28);

</script>

とりあえず、&&でつないで代入すると、最初にfalseになった値か最後の値を代入でき、 ||でつないで代入すると、最初にtrueになった値か最後の値を代入できるという感じです。