正当な生産上の理由、たとえば単体テストハーネスのようなもののために、console.log
への呼び出しを含めたいとします。ブラウザーにconsole
がない場合、または コンソールが存在しない の場合、これが時期尚早の例外をスローすることは望ましくありません。
単純なlog
関数を作成してコンソールにデータを記録する、またはコンソールが存在しない場合はエラーなしでエラーなしで失敗する最良の方法は何ですか?
上記のリンクされた質問に対する受け入れられた回答:
var log = Function.prototype.bind.call(console.log, console); log.apply(console, ["this", "is", "a", "test"]);
このlog
関数はIEで正常に呼び出すことができますか?ここでapply
を使用することは、それが可能であることを示すためだけですか?そして、私はリンクされた質問から、IEのコンソールが実行中に閉じられると失敗するので、log
はコンソールが開いた後でも動作しません、正しいと思いますか?それが間違っている場合、誰かがそれがどのように機能するかを説明できますか?
この ycombinatorの記事 は関連しているようです。彼らは上記の質問と同じIEの振る舞いについて話しているのですか?
Function.prototype.apply.apply(console.log, [console, arguments]);
IE9の破損したconsole.logと、他のベンダーの通常のconsole.logの両方で機能します。 Array.prototype.sliceを使用して引数を実際の配列に変換するのと同じハック。
これは、私のchromeコンソールでうまく機能します。
function echo(){
Function.prototype.apply.apply(console.log, [console, arguments]);
}
簡略化:
function echo(){
Function.apply.call(console.log, console, arguments);
}
チェックを追加して戻ります。
function echo(){
return window.console && console.log &&
Function.apply.call(console.log, console, arguments);
}
上記の例は私には適切に見えます。 IEをテストする手元にはありません。これはconsole.log
を安全にラップするための合理的なアプローチですか?]
その他の質問
以下のnavの回答のリンクをたどると、コードが表示されます。
Function.prototype.call.call(console.log, console,
Array.prototype.slice.call(arguments));
この場合、arguments
を配列に変換する目的は何ですか?これを行わないと、一部のブラウザで失敗するはずです。そして、opera奇妙な振る舞いとコンソールレスブラウザは別として、このようなものは他のすべてのブラウザでも同様に動作するはずではありませんか?prototype
は上記の例、または私たちはただつまらない... Function.call.call
またはObject.call.call
またはその点でisNaN.call.call
はFunction.prototype.call.call
と同様に機能するようです。
IEでこのログ関数を正常に呼び出すことはできますが、ここでapplyを使用すると、それが可能であることを示すことができますか?
はい、そしてはい。この特定の例は、リンクされた質問の"is it real function"の部分を真っ直ぐに狙ったものです。
そして、リンクされた質問から、IEのコンソールが実行中に閉じられた場合、これは失敗するので、コンソールが開いた後でもログが機能しないと思いますか?
正しい。その質問に対する私の答えで説明したように、console
オブジェクトは、特定のタブの開発者ツールが初めて開かれるまで公開されません。ほとんどの開発者はコンソールシムを使用します。その場合、Function#bind
アプローチは、Function#apply.apply
方法。
この場合、引数を配列に変換する目的は何ですか?
ありません、それは冗長です。カスタムlog実装でない限り、その場合、開発者は引数オブジェクトを配列に変換する理由があるかもしれません。
そして、プロトタイプは上記の例で目的を果たしますか、それとも私たちはただの教育的です...
はい、そうです。一部の開発者は、無意識のうちにFunction.call
カスタム関数または値。もちろん、_Function.prototype.call
も、しかしこれは偶然に起こる可能性がはるかに低いです。
ラッパーの問題は、ログメッセージのソースのファイル名と行番号を難読化することです。
他のブラウザーの行番号を保持する単純なIE7以下のシム:
/* console shim*/
(function () {
var f = function () {};
if (!window.console) {
window.console = {
log:f, info:f, warn:f, debug:f, error:f
};
}
}());
申し訳ありませんが、私の投稿にバグがありました。どうして見逃したかわかりません。
グローバルコンソールオブジェクトを作成する適切な方法(存在しない場合):
if (typeof console === "undefined"){
console={};
console.log = function(){
return;
}
}
私は使用したい:
'console' in window && console.log("Boom!");
すべてのブラウザで動作し、理解しやすいです。
以下のコードスニペットを使用してみてください...(これはwindow.consoleから独立させるため、これが私の推奨アプローチです)
var logger = (function (c) {
"use strict";
var m = {
log: function (a, t) {
if (!c) { return; /* return or call your custom function here */ }
var l = c.log,
f = t === undefined ? l : (this.__dict__[t] || l);
f.apply(c, a)
},
__dict__: {
"trace": c.trace,
"debug": c.debug,
"info": c.info,
"warn": c.warn,
"error": c.error
}
};
return {
trace: function () { m.log(arguments, "trace"); },
debug: function () { m.log(arguments, "debug"); },
info: function () { m.log(arguments, "info"); },
warn: function () { m.log(arguments, "warn"); },
error: function () { m.log(arguments, "error"); },
log: function () { m.log(arguments, undefined); }
};
}(window.console))
あなたは今あなたのコードでこれらを試して結果を見ることができます
logger.info("Hello");
logger.trace("Hello");
logger.debug("Hello");
logger.warn("Hello");
logger.error("Hello");
logger.log("Hello");
クリスの答えのわずかなバリエーションとして、空の関数を持つ「コンソール」のプロパティとして「ログ」を定義するだけです。
if (typeof console === "undefined") {
console = {
log: function () {
return;
}
};
}
Paul Irishには、console.log()
のNice light wrapper/replacementがあります。
http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
利点:
log()
またはwindow.log()
のようにすばやく入力できます。coffeescript:
empty_function = ->
return
if !window.console?
window.console = {}
for fn in ['log', 'info', 'warn', 'debug', 'error']
if (typeof window.console[fn] isnt 'function')
window.console[fn] = empty_function
js:
(function() {
var empty_function, fn, i, len, ref;
empty_function = function() {};
if (window.console == null) {
window.console = {};
ref = ['log', 'info', 'warn', 'debug', 'error'];
for (i = 0, len = ref.length; i < len; i++) {
fn = ref[i];
if (typeof window.console[fn] !== 'function') {
window.console[fn] = empty_function;
}
}
}
}).call(this);
私の途方もなく過剰に設計されたコンソール:
console.log
ステートメントを残した場合、本番環境でのログインを防止しますconsole.error
、console.group
、およびそのような他のすべてのメソッドをサポートしますすごい。
しかし、実際には、コードにconsole
ステートメントを置いたままにしないでください。
見よ、震え!提示: Consolation.js