WEB+DB PRESS Vol. 58 に記事を書きました

連載2回目です。前回に引き続き クロスブラウザJavaScript のお話を中心に10ページほど書きました。


  • 関数呼び出しのコスト(どこに関数を置くべきか)
  • eval と Function コンストラク
  • try〜catch を控える
  • 動かないコード(Liveな配列, FakeArray)
  • FizzBuzzコードを例にループ内の最適化ポイントの説明
  • 型の判別(isArray と Arrayを含めたオブジェクトの判別)

前回ほど濃ゆいことは書いてないつもりなので、サラッと読めると思います。

型の判別について補足

IE の window, document, Node などは DOM の仕様とも ECMAScript の仕様とも異なる実装になっています。

IE8までは、typeof window.setTimeout"object" になりますが、Web標準的には "function" です。
IE8までは、Object.prototype.toString.call(window.setTimeout)"[object Object]" になりますが、Web標準的には "[object Function]" です。

同様に document.attachEvent なども "object", "[object Object]" になります。

IE8までのIEは、window I/F, document I/F, Node I/F で定義されている関数が、それが本当に関数なのか、ただのオブジェクトなのかを判別する方法はありません。

以下のように実際に関数として呼び出せるかを試せば、動的に判別も可能かと思いますが(不正な引数を渡すと例外がでてしまうので結局無理なんだけど)、誰もこんな副作用のあるやり方は望んでいないでしょう。

function isFunction(object, name, arg1, arg2, arg3) {
  try {  
    object[name](arg1, arg2, arg3);
  } catch (err) {
    return false; // alert("NOT FUNCTION");
  }
  return true;
}

function dummy() {
}

isFunction(window, "setTimeout", dummy, 0);
isFunction(document, "attachEvent", "click", dummy);  

IEのDOMやCOMまわりの設計の問題なのですが、IE9のppが続々と登場していることもあり、紙面ではこの辺りのお話を盛り込めませんでした。
記事を読む際に参考にしてください。

IE9pp4 では他のブラウザと同じ挙動に修正されている

IE9からは、typeof window.setTimeout が "function" になります。
IE9からは、Object.prototype.toString.call(window.setTimeout) が "[object Function]" になります。

同様に document.attachEvent も "function", "[object Function]" になります。

こちらは良い方向に進んでいますね。