web-dev-qa-db-ja.com

console.log.applyがIE9で機能しない

ホイールを再発明したようですが、どういうわけかこれはInternet Explorer 9では機能しませんが、IE6では機能します。

function debug()
  if(!window.console) { 
    window.console = { log: function() { /* do something */ } };
  }
  console.log.apply(console, arguments);
}

関連: JavaScriptのApply()質問

F12デバッガーは、この「オブジェクト」(console.log)がメソッド「apply」をサポートしていないことを通知します。関数としても認識されていませんか?他の指針やアイデアはありますか?

47
line-o

回答の2番目の部分 最近与えた もこの質問に回答します。これはその複製とは考えないため、便宜上、ここに貼り付けます。

コンソールオブジェクトは標準の一部ではなく、ドキュメントオブジェクトモデルの拡張機能です。他のDOMオブジェクトと同様に、これはHostオブジェクトと見なされ、Objectから継承する必要はなく、ネイティブECMAScript関数やオブジェクトのようにFunctionからのメソッドも継承する必要はありません。これが、適用および呼び出しがこれらのメソッドで定義されていない理由です。 IE 9では、ほとんどのDOMオブジェクトがネイティブECMAScriptタイプから継承するように改善されました。開発者ツールはIE(ただし、組み込みつまり、他のDOMと同じ改善は受けていません。

それだけの価値がある場合でも、小さなbind()マジックを使用して、コンソールメソッドでいくつかのFunction.prototypeメソッドを使用できます。

var log = Function.prototype.bind.call(console.log, console);
log.apply(console, ["this", "is", "a", "test"]);
//-> "thisisatest"

したがって、すべてのconsoleメソッドをIE 9マナー:

if (Function.prototype.bind && window.console && typeof console.log == "object"){
    [
      "log","info","warn","error","assert","dir","clear","profile","profileEnd"
    ].forEach(function (method) {
        console[method] = this.bind(console[method], console);
    }, Function.prototype.call);
}

これにより、「ホスト」関数が「ホスト」関数を呼び出すネイティブ関数に置き換えられます。コードに Function.prototype.bind および Array.prototype.forEach の互換性実装を含めるか、上記のスニペットを次のように書き換えることで、Internet Explorer 8で機能させることができます。これらの方法で使用される手法を組み込みます。

こちらもご覧ください

93
Andy E

ポール・アイリッシュのやり方もあります。これは上記の回答の一部よりも簡単ですが、logは常に配列を出力します(引数が1つしか渡されなかった場合でも)。

// usage: log('inside coolFunc',this,arguments);
// http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
window.log = function(){
  log.history = log.history || [];   // store logs to an array for reference
  log.history.Push(arguments);
  if(this.console){
    console.log( Array.prototype.slice.call(arguments) );
  }
};
5
BishopZ

IEの一部のHostオブジェクト関数は、実際にはJavaScript関数ではないため、applyまたはcallがありません。 (たとえば、alert)。

だからあなたは難しい方法でそれをしなければならないでしょう:

function debug()
  var index;

  if(!window.console) { 
    window.console = { log: function() { /* do something */ } };
  }
  for (index = 0; index < arguments.length; ++index) {
      console.log(arguments[index]);
  }
}
2
T.J. Crowder

私は同じIEトラブルに遭遇し、そのためのルーチンを作成しました。上記のすべての実装ほど豪華ではありませんが、すべての最新のブラウザーで動作します。

私はそれをFirefox(Firebug)でテストしましたIE 7,8,9 Chrome and Opera。それは悪のEVALを利用しますが、開発中にデバッグします。その後、コードをdebug = function () {};に置き換えます。

だからここにあります。

よろしく、ハンス

(function(ns) {
  var msgs = [];

  // IE compatiblity
  function argtoarr (args,from) {
    var a = [];
    for (var i = from || 0; i<args.length; i++) a.Push(args[i]);
    return a;    
  }

  function log(arg) {
    var params = "", format = "", type , output,
        types = {
            "number" : "%d",
            "object" : "{%o}",
            "array" : "[%o]"
        };
    for (var i=0; i<arg.length; i++) {
        params += (params ? "," : "")+"arg["+i+"]";
        type = types[toType(arg[i])] || "%s";
        if (type === "%d" && parseFloat(arg[i]) == parseInt(arg[i], 10)) type = "%f";
        format += (format ? "," : "")+type;
    }
    // opera does not support string format, so leave it out
    output = "console.log("+(window.opera ? "" : "'%f',".replace("%f",format))+"%p);".replace("%p",params);
    eval(output);
  }

  ns.debug = function () {
    msgs.Push(argtoarr(arguments));
    if (console !== undefined) while (msgs.length>0) log(msgs.shift());
  }

})(window);

おっと、私のtoType関数を忘れてしまいました。

function toType(obj) {
    if (obj === undefined) return "undefined";
    if (obj === null) return "null";
    var m = obj.constructor;
    if (!m) return "window";
    m = m.toString().match(/(?:function|\[object)\s*([a-z|A-Z|0-9|_|@]*)/);
    return m[1].toLowerCase();
}
1
Hans Petersen

試してください:

function log(type) {
  if (typeof console !== 'undefined' && typeof console.log !== 'undefined' &&
    console[type] && Function.prototype.bind) {
    var log = Function.prototype.bind.call(console[type], console);
    log.apply(console, Array.prototype.slice.call(arguments, 1));
  }
}
log('info', 'test', 'pass');
log('error', 'test', 'fail');

logdebuginfowarnerrorgroupまたはgroupEndで機能します。

0
Shobhit Sharma

私がこの質問に来た理由は、私が特定のモジュールのconsole.log関数を「スパイシー」にしようとしているため、引数IE 9はそれを壊しました。

@Andy Eの回答は素晴らしく、応募について多くの洞察を助けてくれました。私はIE9をサポートするために同じアプローチをとらないだけなので、私のソリューションは「最新のブラウザー」でのみコンソールを実行しています(最新であることは、私が期待するように動作するすべてのブラウザーを意味します=)

var C = function() {
  var args = Array.prototype.slice.call(arguments);
  var console = window.console;
  args[0]  = "Module X: "+args[0];
  if( typeof console == 'object' && console.log && console.log.apply ){
    console.log.apply(console, args);
  }
};
0
Fabiano Soriani

OK、次のように書くとうまくいきます:

function debug()
  if(!window.console) { 
    window.console = {};
    console.log = function() { /* do something */ };
  }
  console.log.apply(console, arguments);
}

奇妙な動作...しかし、このように書くと、「console.log」が関数として認識されます。

0
line-o