SitePoint: New Articles, Fresh Thinking for Web Developers and Designers

JavaScriptのコーディングティップスはネット上に溢れている。また、JavaScriptに限定されたテクニックではなく、汎用的に使われているテクニックの多くをJavaScriptコーディングに適用できる。しかし注意が必要だ。簡単でよく知られた方法であっても、文脈を考えずに盲目的に適用すると問題を起こすことがある。この面白いサンプルがCraig Buckler氏によってSitePointにHow to Write Faster JavaScript Condition Expressionsとして掲載されている。

Craig Buckler氏はまず次の条件文を紹介。最初の条件はfalseになるので、次のyを評価する。yはtrueだから、全体としての評価はtrueになる。

var x = 10;
var y = true;
if (x*x > 1000 || y) alert("true!");

これはよくいわれるテクニックだが、こういう場合は次のようにyを先に評価するようにする。こうすればyがtrueと評価された時点で、次の式は評価せずに飛ばすようになるため、実行速度がその分速くなる。関数コールを伴うような処理であったり、数値計算を伴うものであったり、重い処理ほどあとにしたほうが効率がいいというわけだ。論理和(||)ではなく論理積(&&)の場合も同じだ。処理の軽い式を先に持ってくる。それがfalseであればその時点で分残りの式が評価されずに済む。

if (y || x*x > 1000) alert("true!");

次は要素を取得して内容を表示するコードのサンプルが掲載されている。よく使われるコーディングだ。対象となる要素が存在すれば処理が実行され、そうでなければ飛ばされる。

if (summary = document.getElementById("post-summary")) {
  alert(summary.innerHTML);
}

これを論理和(||)と組み合わせると次のようになる。最初のテクニックに従えば、軽い処理を先に持ってきた方が処理速度は高速になる。そのティップスに従うなら正しいコーディングのようにみえるが、このコーディングは間違っている。xがtrueの場合、y = functionY()の処理が実行されないまま、alert(y)が実行されてしまうからだ。

if (x || y = functionY()) {
  alert(y);
}

このため次のように記述する必要がある。

if (y = functionY() || x)

最初で紹介されている条件式の書き方の高速化テクニックだけに注目すると、このコードは効率が悪いように見えるが、今回のケースではこの順番で評価されないと問題がでる。このようにティップスだけを適用して最適化すると異なる手順で処理が実施されてしまい、バグが発生することがある。How to Write Faster JavaScript Condition Expressionsで紹介されているサンプルはわかりやすく、そして犯しがちなコーディングになっており参考になる。