web-dev-qa-db-fra.com

Comment emballer en toute sécurité `console.log`?

Supposons que je veuille inclure certains appels à console.log pour une raison de production légitime, par exemple pour un système de test unitaire. Évidemment, je ne voudrais pas que cela jette une exception prématurée si le navigateur n’a pas de variable console, ou si aucune console n’est présente .

Quel est le meilleur moyen de créer une simple fonction log pour consigner des éléments dans la console ou d’échouer en mode silencieux sans erreur si aucune console n’est présente?

La réponse acceptée à la question liée ci-dessus:

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

Cette fonction log peut-elle être appelée normalement sur IE, et l'utilisation de apply ici est simplement destinée à montrer que c'est possible? Et, d'après la question liée, je suppose que cela échouera si la console d'IE est fermée lors de son exécution. log ne fonctionnera pas même après l'ouverture de la console, n'est-ce pas? Si cela ne va pas, quelqu'un peut-il expliquer comment cela fonctionne? 

Cet article combinateur semble pertinent. Parlent-ils du même comportement IE que la question ci-dessus?

Function.prototype.apply.apply(console.log, [console, arguments]);

Fonctionne à la fois sur le fichier console.log rompu avec IE9 et sur le fichier console.log standard provenant d'autres fournisseurs . Même hack que l'utilisation de Array.prototype.slice pour convertir les arguments en un tableau réel.

Cela fonctionne bien dans ma console chrome.

function echo(){
  Function.prototype.apply.apply(console.log, [console, arguments]);
}

Simplifié:

function echo(){
  Function.apply.call(console.log, console, arguments);
}

Ajouter un chèque et retourner:

function echo(){
  return window.console && console.log &&
         Function.apply.call(console.log, console, arguments);
}

L'exemple ci-dessus me semble adéquat. Je n'ai pas IE sous la main pour le tester, cependant. Est-ce une approche raisonnable pour emballer en toute sécurité console.log?


Plus de questions

En suivant le lien dans la réponse de nav ci-dessous, nous voyons le code:

Function.prototype.call.call(console.log, console,
    Array.prototype.slice.call(arguments));

Quel est le but de la conversion de arguments en un tableau dans ce cas? Je suppose que cela doit échouer dans certains navigateurs si vous ne le faites pas? De plus, à part le comportement étrange de l'opéra et les navigateurs sans console, ne devrait-il pas en être de même pour tous les autres navigateurs? Et prototype sert-il un objectif dans les exemples ci-dessus, ou sommes-nous simplement pédants ... Function.call.call ou Object.call.call ou d'ailleurs isNaN.call.call semblent fonctionner aussi bien que Function.prototype.call.call

47
Dagg Nabbit

Cette fonction de journalisation peut-elle être appelée normalement sur IE et l'utilisation de apply ici est simplement destinée à montrer que c'est possible?

Oui et oui. Cet exemple particulier visait directement le "est-ce une fonction réelle" une partie de la question liée.

Et, je suppose que d'après la question liée, cela échouera si la console d'IE est fermée lors de son exécution. Le journal ne fonctionnera donc pas même après l'ouverture de la console, n'est-ce pas?

Correct. Comme expliqué dans ma réponse à cette question, l'objet console n'est exposé que lorsque les outils de développement sont ouverts pour la première fois pour un onglet particulier. La plupart des développeurs utilisent un shim de console, auquel cas l'approche Function#bind devient un peu obsolète, car vous pouvez également utiliser la méthode Function#apply.apply.

Quel est le but de convertir des arguments en un tableau dans ce cas? 

Il n'y en a pas, c'est redondant. Sauf s'il s'agit d'une implémentation log personnalisée, dans ce cas, le développeur peut avoir une raison de convertir un objet arguments en un tableau.

Et le prototype a-t-il une utilité dans les exemples ci-dessus, ou sommes-nous simplement pédants ... 

Eh bien oui et non. Certains développeurs peuvent avoir modifié involontairement Function.call en une fonction ou une valeur personnalisée. Bien sûr, ils pourraient aussi casser Function.prototype.call, mais cela est beaucoup moins susceptible de se produire par accident.

7
Andy E

Le problème avec les wrappers est qu’ils masqueront le nom de fichier et le numéro de ligne de la source du message de journal. 

IE7 simple et inférieur qui préserve la numérotation des lignes pour les autres navigateurs:

/* console shim*/
(function () {
    var f = function () {};
    if (!window.console) {
        window.console = {
            log:f, info:f, warn:f, debug:f, error:f
        };
    }
}());
20
dbrin

Désolé, il y avait un bug dans mon post. Je ne sais pas comment ça m'a manqué.

La meilleure façon de créer un objet de console global, s’il n’existe pas:

if (typeof console === "undefined"){
    console={};
    console.log = function(){
        return;
    }
}
16
ChrisN

J'aime utiliser:

'console' in window && console.log("Boom!");

Cela fonctionne dans tous les navigateurs et est facile à comprendre.

6
etoxin

Essayez d’utiliser l’extrait de code ci-dessous ... (c’est mon approche préférée car elle vous rend indépendant de 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))

Donc, vous pouvez maintenant essayer ces dans votre code et voir le résultat

logger.info("Hello");
logger.trace("Hello");
logger.debug("Hello");
logger.warn("Hello");
logger.error("Hello");
logger.log("Hello");
3
Ammar Hasan

Comme légère variation de la réponse de Chris, définissez simplement 'log' comme propriété de 'console' avec une fonction vide:

if (typeof console === "undefined") {
    console = {
        log: function () {
            return;
        } 
   };
}
1
dougajmcdonald

Paul Irish a un emballage/remplacement léger de Nice pour console.log().

http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/

Avantages:

  • Empêcher les erreurs si une console n’est pas disponible (IE)
  • Conserve un historique des journaux afin que vous puissiez regarder dans le passé si votre console est ajoutée par la suite (par exemple, Firebug Lite)
  • Léger et simple.
  • Très rapide à taper - log() ou window.log().
0
Thomas W

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

Utiliser la consolation

Ma console ridiculement sur-conçue:

  • empêche les erreurs s'il n'y a pas de console
  • empêche la connexion en production si vous avez laissé des instructions console.log dans votre code
  • prend en charge console.error, console.group et toutes ces autres méthodes
  • vous donne toujours des traces à vos relevés de journal

C'est incroyable. 

Mais en réalité, vous ne devriez pas laisser de déclarations console dans votre code.

Voici et tremblons! Présentation: Consolation.js

0
Nathan Long