Help us understand the problem. What is going on with this article?

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

More than 5 years have passed since last update.

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

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滅んで欲しい。

k_ui
ねこほしい
http://k-ui.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away