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
.
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.
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
};
}
}());
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;
}
}
J'aime utiliser:
'console' in window && console.log("Boom!");
Cela fonctionne dans tous les navigateurs et est facile à comprendre.
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");
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;
}
};
}
Paul Irish a un emballage/remplacement léger de Nice pour console.log()
.
http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
Avantages:
log()
ou 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);
Ma console ridiculement sur-conçue:
console.log
dans votre codeconsole.error
, console.group
et toutes ces autres méthodesC'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