Подтвердить что ты не робот

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

Отладчик F12 сообщает мне, что этот "объект" (console.log) не поддерживает метод "apply". Разве это даже не признается как функция? Любые другие указатели или идеи?

4b9b3361

Ответ 1

Вторая часть ответа который я дал недавно, также отвечает на этот вопрос. Я не считаю это дубликат этого, поэтому, для удобства, я вставьте его здесь:

Консольный объект не является частью какого-либо стандарта и является расширением для объектной модели документа. Как и другие объекты DOM, он считается объектом-хозяином и не требуется наследовать от Object, а также его методы из Function, такие как функции ECMAScript и объекты. Это причина, по которой применяются и называются undefined для этих методов. В IE 9 большинство объектов DOM были улучшены, чтобы наследовать от родных типов ECMAScript. Поскольку инструменты разработчика считаются расширением IE (хотя и встроенным расширением), они явно не получили тех же улучшений, что и остальные DOM.

Для чего вы стоите, вы можете использовать некоторые методы 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);
}

Это заменяет функции "хозяина" на собственные функции, которые вызывают функции "хозяина". Вы можете заставить его работать в Internet Explorer 8, включив реализации совместимости для Function.prototype.bind и Array.prototype.forEach в вашем коде или переписать вышеприведенный фрагмент, чтобы включить методы, используемые этими методами.

См. также

Ответ 2

Существует также польский ирландский способ сделать это. Это проще, чем некоторые из приведенных выше ответов, но делает журнал всегда выводит массив (даже если был передан только один аргумент):

// 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) );
  }
};

Ответ 3

Некоторые из функций объекта хоста IE на самом деле не являются функциями 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]);
  }
}

Ответ 4

Я столкнулся с той же проблемой IE и сделал рутину для нее. Это не так причудливо, как все вышеперечисленные реализации, но работает во всех современных браузерах.

Я тестировал его с Firefox (Firebug), IE 7,8,9 Chrome и 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();
}

Ответ 5

Хорошо, он работает, когда вы пишете его так:

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

Нечетное поведение... но если вы напишете это так, "console.log" распознается как функция.

Ответ 6

Причина, по которой я пришел к этому вопросу, заключалась в том, что я пытаюсь "spicy" для функции 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);
  }
};

Ответ 7

Try:

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');

Работает для log, debug, info, warn, error, group или groupEnd.