具有正确行号的控制台.log的正确包装器?

2022-08-30 02:01:18

我现在正在开发一个应用程序,并放置一个全局开关。我想包装以方便使用。isDebugconsole.log

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

然后我在Firefox控制台中得到这个结果。

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

如果我想用被调用的行号记录,比如?debug()info: Here is a msg. main.js (line 2)


答案 1

这是一个老问题,提供的所有答案都过于黑客化,有主要的跨浏览器问题,并且没有提供任何超级有用的东西。此解决方案适用于每个浏览器,并完全按照应有的方式报告所有控制台数据。无需黑客攻击和一行代码 签出代码笔

var debug = console.log.bind(window.console)

创建开关,如下所示:

isDebug = true // toggle this to turn on / off for global controll

if (isDebug) var debug = console.log.bind(window.console)
else var debug = function(){}

然后只需按如下方式调用:

debug('This is happening.')

您甚至可以像这样接管控制台.log交换机:

if (!isDebug) console.log = function(){}

如果你想用它做一些有用的事情。.您可以添加所有控制台方法并将其包装在一个可重用的函数中,该函数不仅提供全局控制,还提供类级别:

var Debugger = function(gState, klass) {

  this.debug = {}

  if (gState && klass.isDebug) {
    for (var m in console)
      if (typeof console[m] == 'function')
        this.debug[m] = console[m].bind(window.console, klass.toString()+": ")
  }else{
    for (var m in console)
      if (typeof console[m] == 'function')
        this.debug[m] = function(){}
  }
  return this.debug
}

isDebug = true //global debug state

debug = Debugger(isDebug, this)

debug.log('Hello log!')
debug.trace('Hello trace!')

现在,您可以将其添加到您的类中:

var MyClass = function() {
  this.isDebug = true //local state
  this.debug = Debugger(isDebug, this)
  this.debug.warn('It works in classses')
}

答案 2

我喜欢@fredrik的答案,所以我用另一个拆分Webkit stacktrace的答案将其汇总,并将其与@PaulIrish的安全控制台.log包装器合并。将“标准化”为“特殊对象”,使其脱颖而出,并且在FF和Chrome中看起来大致相同。filename:line

小提琴测试:http://jsfiddle.net/drzaus/pWe6W/

_log = (function (undefined) {
    var Log = Error; // does this do anything?  proper inheritance...?
    Log.prototype.write = function (args) {
        /// <summary>
        /// Paulirish-like console.log wrapper.  Includes stack trace via @fredrik SO suggestion (see remarks for sources).
        /// </summary>
        /// <param name="args" type="Array">list of details to log, as provided by `arguments`</param>
        /// <remarks>Includes line numbers by calling Error object -- see
        /// * http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
        /// * https://stackoverflow.com/questions/13815640/a-proper-wrapper-for-console-log-with-correct-line-number
        /// * https://stackoverflow.com/a/3806596/1037948
        /// </remarks>

        // via @fredrik SO trace suggestion; wrapping in special construct so it stands out
        var suffix = {
            "@": (this.lineNumber
                    ? this.fileName + ':' + this.lineNumber + ":1" // add arbitrary column value for chrome linking
                    : extractLineNumberFromStack(this.stack)
            )
        };

        args = args.concat([suffix]);
        // via @paulirish console wrapper
        if (console && console.log) {
            if (console.log.apply) { console.log.apply(console, args); } else { console.log(args); } // nicer display in some browsers
        }
    };
    var extractLineNumberFromStack = function (stack) {
        /// <summary>
        /// Get the line/filename detail from a Webkit stack trace.  See https://stackoverflow.com/a/3806596/1037948
        /// </summary>
        /// <param name="stack" type="String">the stack string</param>

        if(!stack) return '?'; // fix undefined issue reported by @sigod

        // correct line number according to how Log().write implemented
        var line = stack.split('\n')[2];
        // fix for various display text
        line = (line.indexOf(' (') >= 0
            ? line.split(' (')[1].substring(0, line.length - 1)
            : line.split('at ')[1]
            );
        return line;
    };

    return function (params) {
        /// <summary>
        /// Paulirish-like console.log wrapper
        /// </summary>
        /// <param name="params" type="[...]">list your logging parameters</param>

        // only if explicitly true somewhere
        if (typeof DEBUGMODE === typeof undefined || !DEBUGMODE) return;

        // call handler extension which provides stack trace
        Log().write(Array.prototype.slice.call(arguments, 0)); // turn into proper array
    };//--  fn  returned

})();//--- _log

这也适用于 node,您可以使用以下命令对其进行测试:

// no debug mode
_log('this should not appear');

// turn it on
DEBUGMODE = true;

_log('you should', 'see this', {a:1, b:2, c:3});
console.log('--- regular log ---');
_log('you should', 'also see this', {a:4, b:8, c:16});

// turn it off
DEBUGMODE = false;

_log('disabled, should not appear');
console.log('--- regular log2 ---');