サイトトップ

Director Flash 書籍 業務内容 プロフィール

HTML5テクニカルノート

論理演算子を使った条件判定

ID: FN1212002 Technique: HTML5 and JavaScript

論理和演算子||や論理積演算子&&は、ほとんどの場合if文などの分岐処理に条件として使われます。けれど、これらの論理演算子だけで条件判定の処理ができることもあります。


01 関数があったら呼出す

たとえば、関数を呼出そうとするとき、その関数があるのかどうか先に確かめるという処理を考えます。コールバック関数を呼出すときなどは、その設定がまだ済んでいないこともあるでしょう。if文で書けば、つぎのようなJavaScriptコードになります。if条件に定めた関数(callback)がなければ値はundefinedですので、条件としての評価はfalseとなり、その呼出しは行われません。関数があれば、オブジェクトはtrueと評価されるため、関数が呼出されます。

if (callback) {
  callback();
}

このif文と同じ内容の処理は、論理積演算子&&を用いれば、つぎのように1行で書けます。論理積演算子&&はまず左オペランド(被演算子)をブール(論理)値評価し、結果の値がfalseであれば、もはや右オペランドの評価そのものを省くのです。そのため、関数は呼出されません。左オペランドがtrueと評価されて初めて、右オペランドを評価するために関数は呼出されることになります[*1]

callback && callback();

以下にテスト用のJavaScriptコードを掲げました。テスト用の関数(test())を用意して、変数(callback)に代入しています(第1〜2行目)。すると、上述のとおり左オペランドの変数はtrueとブール値評価されるため、右オペランドの関数呼出しが行われます(第3行目)。関数は呼出されると、確認用の警告ダイアログボックスを開きます(図001)。

  1. var callback;
  2. callback = test;
  3. callback && callback();
  4. function test() {
  5.   alert("called");
  6. }

図001■関数が呼出されると警告ダイアログボックスを開く
図001

つぎに、変数に関数が代入されるステートメントをコメントアウトすれば、警告ダイアログボックスは表示されません。したがって、関数は呼出されていないことが確かめられます。

// callback = test;
callback && callback();

[*1] 実装例としては、EaselJSライブラリのEventDispatcherクラスが挙げられます(本稿執筆時点では、まだ正規リリースはされていません)。EventDispatcher.dispatchEvent()メソッドは、引数のコールバック関数があるかどうか論理積演算子&&を確かめたうえで、あった場合にFunction.apply()メソッドにより関数を呼出しています(図002)。

図002■論理積演算子&&で関数の存在を確かめてからFunction.apply()メソッドにより呼出す
図002


02 初期化されていない変数に値を与える

変数がまだ値をもっていないとき、デフォルト値を加えたいことがあります。たとえば、ユーザーに入力してもらうテキストが与えられていないときに、デフォルトの文字列を変数に入れる場合です。変数に値がなかったり、空文字列""が納められていると、ブール値としての評価はfalseになります。したがって、if文ではつぎのようなJavaScriptコードを書けばよいでしょう。

もし、変数(input)の値が未定義(undefined)または空文字列""であれば、ブール値評価された値falseが論理否定演算子!によりtrueに反転します。したがって、この場合には変数にデフォルト値が与えられることになります。すでに変数に文字列が納められていたら、値はそのまま変わりません。

if (!input) {
  input = "デフォルト値";
}

同じ処理は、つぎのように条件演算子?:を使ってもできます。変数(input)に空文字列""以外の文字列が入っていれば、その値が改めて変数に代入されます。そうでない場合には、変数にデフォルト値が納められることになります。

input = input ? input : "デフォルト値";

論理和演算子||を使えば、以下のようにさらに短く書けます。この処理を理解するには、「論理和(||)と論理積(&&)演算子」が返すのはオペランドをブール値評価した値ではなく、オペランドの値そのものであることを知らなければなりません(リンクしたノートの表002参照)。

変数(input)に空文字列""でない文字列が入っていれば、左オペランドのブール値評価はtrueです。その場合に返されて変数に代入されるのは、左オペランドそのものの値、つまり中に入っている文字列になります。そして、左オペランドがfalseと評価されると、右オペランドはもはやブール値として評価することなく、その値をそのまま返すのです。したがって、変数にデフォルト値が納められます。

input = input || "デフォルト値";

[*2] 実装例としては、CreateJSライブラリの名前空間(createjs)があります。同じ名前空間(Objectインスタンス)を複数のクラスで共用したい場合で、しかもそれらの読込み順を固定しないためには、名前空間がまだなかったら初期化し、あったらそれを使うようにしたいです。CreateJSライブラリのクラスは、論理和演算子||を用いて名前空間を確かめて、なければ新たなObjectインスタンスを納めています(図003)。

図003■CreateJSライブラリのDisplayObjectクラスの名前空間createjsの設定
図003

論理和演算子||の処理をif文と比べたとき、その中身にことさら優れた点は点は見当たりません。ただ、数多くのクラスを統合したライブラリでは、コードそのものを短くすることで、データのサイズやロードの負荷を減らせることがあるでしょう。


作成者: 野中文雄
作成日: 2012年12月12日


Copyright © 2001-2012 Fumio Nonaka.  All rights reserved.