172 votes

Un wrapper approprié pour console.log avec un numéro de ligne correct ?

Je suis en train de développer une application, et je place une commande globale isDebug un interrupteur. Je voudrais envelopper console.log pour une utilisation plus pratique.

//isDebug controls the entire site.
var isDebug = true;

//debug.js
function debug(msg, level){
    var Global = this;
    if(!(Global.isDebug && Global.console && Global.console.log)){
        return;
    }
    level = level||'info';
    Global.console.log(level + ': '+ msg);
}

//main.js
debug('Here is a msg.');

J'obtiens alors ce résultat dans la console de Firefox.

info: Here is a msg.                       debug.js (line 8)

Et si je veux enregistrer avec le numéro de ligne où debug() est appelé, comme info: Here is a msg. main.js (line 2) ?

0voto

Feng Li Points 9
window.line = function () {
    var error = new Error(''),
        brower = {
            ie: !-[1,], // !!window.ActiveXObject || "ActiveXObject" in window
            opera: ~window.navigator.userAgent.indexOf("Opera"),
            firefox: ~window.navigator.userAgent.indexOf("Firefox"),
            chrome: ~window.navigator.userAgent.indexOf("Chrome"),
            safari: ~window.navigator.userAgent.indexOf("Safari"), // /^((?!chrome).)*safari/i.test(navigator.userAgent)?
        },
        todo = function () {
            // TODO: 
            console.error('a new island was found, please told the line()\'s author(roastwind)');        
        },
        line = (function(error, origin){
            // line, column, sourceURL
            if(error.stack){
                var line,
                    baseStr = '',
                    stacks = error.stack.split('\n');
                    stackLength = stacks.length,
                    isSupport = false;
                // macchrome(55.0.2883.95 (64-bit))
                if(stackLength == 11 || brower.chrome){
                    line = stacks[3];
                    isSupport = true;
                // macsafari(10.0.1 (12602.2.14.0.7))
                }else if(brower.safari){
                    line = stacks[2];
                    isSupport = true;
                }else{
                    todo();
                }
                if(isSupport){
                    line = ~line.indexOf(origin) ? line.replace(origin, '') : line;
                    line = ~line.indexOf('/') ? line.substring(line.indexOf('/')+1, line.lastIndexOf(':')) : line;
                }
                return line;
            }else{
                todo();
            }
            return '';
        })(error, window.location.origin);
    return line;
}
window.log = function () {
    var _line = window.line.apply(arguments.callee.caller),
        args = Array.prototype.slice.call(arguments, 0).concat(['\t\t\t@'+_line]);
    window.console.log.apply(window.console, args);
}
log('hello');

Voici ma solution à cette question. Lorsque vous appelez la méthode : log, le numéro de la ligne où vous avez imprimé votre log sera imprimé.

0voto

La façon dont j'ai résolu le problème a été de créer un objet, puis de créer une nouvelle propriété sur l'objet en utilisant la commande Object.defineProperty() et renvoie la propriété de la console, qui est alors utilisée comme la fonction normale, mais maintenant avec la capacité étendue.

var c = {};
var debugMode = true;

var createConsoleFunction = function(property) {
    Object.defineProperty(c, property, {
        get: function() {
            if(debugMode)
                return console[property];
            else
                return function() {};
        }
    });
};

Ensuite, pour définir une propriété, il suffit de faire...

createConsoleFunction("warn");
createConsoleFunction("log");
createConsoleFunction("trace");
createConsoleFunction("clear");
createConsoleFunction("error");
createConsoleFunction("info");

Et maintenant vous pouvez utiliser votre fonction comme

c.error("Error!");

0voto

Re-beat Points 16

Sur la base d'autres réponses (principalement celle de @arctelix), j'ai créé ceci pour Node ES6, mais un test rapide a montré de bons résultats dans le navigateur également. Je passe juste l'autre fonction comme une référence.

let debug = () => {};
if (process.argv.includes('-v')) {
    debug = console.log;
    // debug = console; // For full object access
}

0voto

Zelgadis Points 729

Avec le javascript moderne et l'utilisation de getters, vous pourriez écrire quelque chose comme ceci :

window.Logger = {
    debugMode: true,
    get info() {
        if ( window.Logger.debugMode ) {
            return window.console.info.bind( window.console );
        } else {
            return () => {};
        }
    }
}

L'avantage de ce système est qu'il permet d'imprimer à la fois les valeurs statiques et calculées, ainsi que les numéros de ligne corrects. Vous pouvez même définir plusieurs enregistreurs avec des paramètres différents :

class LoggerClz {
    name = null;
    debugMode = true;
    constructor( name ) { this.name = name; }
    get info() {
        if ( this.debugMode ) {
            return window.console.info.bind( window.console, 'INFO', new Date().getTime(), this.name );
        } else {
            return () => {};
        }
    }
}

const Logger1 = new LoggerClz( 'foo' );
const Logger2 = new LoggerClz( 'bar' );

function test() {
    Logger1.info( '123' ); // INFO 1644750929128 foo 123 [script.js:18] 
    Logger2.info( '456' ); // INFO 1644750929128 bar 456 [script.js:19] 
}
test();

0voto

Besworks Points 276

Vous pouvez utiliser chaînage facultatif pour vraiment simplifier les choses. Vous obtenez un accès complet à l'objet console, sans bidouillage et avec une syntaxe concise.

const debug = (true) ? console : null;

debug?.log('test');
debug?.warn('test');
debug?.error('test')

Si debug == null tout ce qui suit le ? est ignorée et aucune erreur n'est signalée concernant les propriétés inaccessibles.

const debug = (false) ? console : null;
debug?.error('not this time');

Cela vous permet également d'utiliser l'objet de débogage directement comme conditionnel pour d'autres processus liés au débogage que la journalisation.

const debug = (true) ? console : null;

let test = false;

function doSomething() {
  test = true;
  debug?.log('did something');
}

debug && doSomething();

if (debug && test == false) {
  debug?.warn('uh-oh');
} else {
  debug?.info('perfect');
}

if (!debug) {
  // set up production
}

Si vous le souhaitez, vous pouvez surcharger les différentes méthodes avec un paramètre de type no-op en fonction du niveau de journalisation souhaité.

const debug = (true) ? console : null;
const quiet = true; const noop = ()=>{};

if (debug && quiet) {
  debug.info = noop;
  debug.warn = noop;
}

debug?.log('test');
debug?.info('ignored in quiet mode');
debug?.warn('me too');

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X