console.log を短く書くために(IE8+ 対応)

  • 19
    いいね
  • 3
    コメント
この記事は最終更新日から1年以上が経過しています。

以前書いた が基本的にはこう書けば良い:

var log = console.log.bind(console);

log('hoge: %s', 'fuga');
// => hoge: fuga

今回はこれに IE8+ 対応を加えたものについて書く。

イマイチな例

可変長引数を残しつつ bind 使わずにこう書く:

var log = function() {
  var args = Array.prototype.slice(arguments);
  console.log.apply(console, args);
};

これをやると、Google Chrome の開発者ツールのログ出力の右端にでる ファイル名:行数 の表示が常に apply の場所になってしまうのでイマイチ。

少し関係ないけれど Array.prototype.slice(arguments) のように arguments を他所のスコープに持って行くと V8 エンジンの最適化を殺すことになるらしい。このあたりは実感ないので若干扱いに困ってる。

IE8+ 対応

今回は IE8+ で動作確認済みの例:

var log = (function(){
  if (!(console && console.log)) {
    // IE8-9 は開発者ツールを閉じると console が無くなるので諦める
    return function() {};
  }

  if (!console.log.bind) {
    // bind が使えないケース(IE8-9など)では apply を使う。
    return function() {
      var a = Array.prototype.slice.call(arguments);
      Function.prototype.apply.call(console.log, console, a);
    };
  }

  // IE10+ ではこれが使われるはず
  return console.log.bind(console);
})();

先ほどの「イマイチな例」でダメだと言われていた slice を使っているけれど、ここの処理は V8 では動かないはずなのでこれでいいかなーという感じ。

Function.prototype.apply.call(...) のようにややこしく、console.log.apply を直接使わない理由は、そもそも IE10 以前では console.log が Function じゃないため apply を持っていないから。。。

IE8-9のコンソール
typeof console.log
// => "object"
typeof console.log.apply
// => "undefined"

コード中に書いてあるとおり console が消えるので、短く書ける以外にも Polyfill 的な意味も含まれている。

はーIE滅んで欲しい。