Edited at

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

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