Ruf*_*fus 119 javascript
我现在正在开发一个应用程序,并放置一个全局isDebug开关.我想换行console.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.');
Run Code Online (Sandbox Code Playgroud)
然后我在Firefox控制台中得到了这个结果.
info: Here is a msg. debug.js (line 8)
Run Code Online (Sandbox Code Playgroud)
如果我想用debug()被调用的行号记录,info: Here is a msg. main.js (line 2)怎么办?
arc*_*lix 109
这是一个老问题,提供的所有答案都过于hackey,有主要的跨浏览器问题,并且没有提供任何超级有用的东西.此解决方案适用于每个浏览器,并准确报告所有控制台数据.不需要黑客和一行代码检查代码.
var debug = console.log.bind(window.console)
Run Code Online (Sandbox Code Playgroud)
像这样创建开关:
isDebug = true // toggle this to turn on / off for global controll
if (isDebug) var debug = console.log.bind(window.console)
else var debug = function(){}
Run Code Online (Sandbox Code Playgroud)
然后简单地调用如下:
debug('This is happening.')
Run Code Online (Sandbox Code Playgroud)
您甚至可以使用如下开关接管console.log:
if (!isDebug) console.log = function(){}
Run Code Online (Sandbox Code Playgroud)
如果你想做一些有用的东西..你可以添加所有控制台方法并将其包装在一个可重用的函数中,该函数不仅提供全局控制,还提供类级别:
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!')
Run Code Online (Sandbox Code Playgroud)
现在您可以将它添加到您的类:
var MyClass = function() {
this.isDebug = true //local state
this.debug = Debugger(isDebug, this)
this.debug.warn('It works in classses')
}
Run Code Online (Sandbox Code Playgroud)
drz*_*aus 23
我喜欢@fredrik的答案,所以我将另一个答案拆分为Webkit 堆栈跟踪,并将其与@PaulIrish的安全console.log包装器合并."标准化" filename:line为"特殊对象",因此它在FF和Chrome中看起来大致相同.
小提琴测试: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
Run Code Online (Sandbox Code Playgroud)
这也适用于节点,您可以使用以下方法对其进行测试:
// 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 ---');
Run Code Online (Sandbox Code Playgroud)
nam*_*uol 15
您可以通过以下方式巧妙地使用以下内容来维护行号并输出日志级别Function.prototype.bind:
function setDebug(isDebug) {
if (window.isDebug) {
window.debug = window.console.log.bind(window.console, '%s: %s');
} else {
window.debug = function() {};
}
}
setDebug(true);
// ...
debug('level', 'This is my message.'); // --> level: This is my message. (line X)
Run Code Online (Sandbox Code Playgroud)
更进一步,你可以利用console错误/警告/信息区别,仍然有自定义级别.试试吧!
function setDebug(isDebug) {
if (isDebug) {
window.debug = {
log: window.console.log.bind(window.console, '%s: %s'),
error: window.console.error.bind(window.console, 'error: %s'),
info: window.console.info.bind(window.console, 'info: %s'),
warn: window.console.warn.bind(window.console, 'warn: %s')
};
} else {
var __no_op = function() {};
window.debug = {
log: __no_op,
error: __no_op,
warn: __no_op,
info: __no_op
}
}
}
setDebug(true);
// ...
debug.log('wat', 'Yay custom levels.'); // -> wat: Yay custom levels. (line X)
debug.info('This is info.'); // -> info: This is info. (line Y)
debug.error('Bad stuff happened.'); // -> error: Bad stuff happened. (line Z)
Run Code Online (Sandbox Code Playgroud)
ang*_*iel 12
听着 McFly,这是唯一对我有用的东西:
let debug = true;
Object.defineProperty(this, "log", {get: function () {
return debug ? console.log.bind(window.console, '['+Date.now()+']', '[DEBUG]')
: function(){};}
});
// usage:
log('Back to the future');
// outputs:
[1624398754679] [DEBUG] Back to the future
Run Code Online (Sandbox Code Playgroud)
这样做的好处是避免另一个函数调用,例如log('xyz')()
创建包装对象甚至类。ES5 也是安全的。
如果您不需要前缀,只需删除该参数即可。
更新包括当前时间戳作为每个日志输出的前缀。
来自:如何获取JavaScript来电者功能行号?如何获取JavaScript调用者源URL?
该Error对象具有行号属性(在FF中).所以像这样的东西应该工作:
var err = new Error();
Global.console.log(level + ': '+ msg + 'file: ' + err.fileName + ' line:' + err.lineNumber);
Run Code Online (Sandbox Code Playgroud)
在Webkit浏览器中,您有err.stack一个表示当前调用堆栈的字符串.它将显示当前行号和更多信息.
UPDATE
要获得正确的亚麻布,您需要在该行上调用错误.就像是:
var Log = Error;
Log.prototype.write = function () {
var args = Array.prototype.slice.call(arguments, 0),
suffix = this.lineNumber ? 'line: ' + this.lineNumber : 'stack: ' + this.stack;
console.log.apply(console, args.concat([suffix]));
};
var a = Log().write('monkey' + 1, 'test: ' + 2);
var b = Log().write('hello' + 3, 'test: ' + 4);
Run Code Online (Sandbox Code Playgroud)
您可以将行号传递给调试方法,如下所示:
//main.js
debug('Here is a msg.', (new Error).lineNumber);
Run Code Online (Sandbox Code Playgroud)
在这里,(new Error).lineNumber将为您提供javascript代码中的当前行号.
保持行号的方法如下:https://gist.github.com/bgrins/5108712.它或多或少归结为:
if (Function.prototype.bind) {
window.log = Function.prototype.bind.call(console.log, console);
}
else {
window.log = function() {
Function.prototype.apply.call(console.log, console, arguments);
};
}
Run Code Online (Sandbox Code Playgroud)
如果你没有调试,你可以用它包装isDebug并设置window.log为function() { }.
我找到了一个简单的解决方案,将接受的答案(绑定到console.log/error/etc)与一些外部逻辑相结合,以过滤实际记录的内容.
// or window.log = {...}
var log = {
ASSERT: 1, ERROR: 2, WARN: 3, INFO: 4, DEBUG: 5, VERBOSE: 6,
set level(level) {
if (level >= this.ASSERT) this.a = console.assert.bind(window.console);
else this.a = function() {};
if (level >= this.ERROR) this.e = console.error.bind(window.console);
else this.e = function() {};
if (level >= this.WARN) this.w = console.warn.bind(window.console);
else this.w = function() {};
if (level >= this.INFO) this.i = console.info.bind(window.console);
else this.i = function() {};
if (level >= this.DEBUG) this.d = console.debug.bind(window.console);
else this.d = function() {};
if (level >= this.VERBOSE) this.v = console.log.bind(window.console);
else this.v = function() {};
this.loggingLevel = level;
},
get level() { return this.loggingLevel; }
};
log.level = log.DEBUG;
Run Code Online (Sandbox Code Playgroud)
用法:
log.e('Error doing the thing!', e); // console.error
log.w('Bonus feature failed to load.'); // console.warn
log.i('Signed in.'); // console.info
log.d('Is this working as expected?'); // console.debug
log.v('Old debug messages, output dominating messages'); // console.log; ignored because `log.level` is set to `DEBUG`
log.a(someVar == 2) // console.assert
Run Code Online (Sandbox Code Playgroud)
console.assert使用条件记录.如果您只是想控制是否使用调试并具有正确的行号,您可以这样做:
if(isDebug && window.console && console.log && console.warn && console.error){
window.debug = {
'log': window.console.log,
'warn': window.console.warn,
'error': window.console.error
};
}else{
window.debug = {
'log': function(){},
'warn': function(){},
'error': function(){}
};
}
Run Code Online (Sandbox Code Playgroud)
当您需要访问调试时,可以这样做:
debug.log("log");
debug.warn("warn");
debug.error("error");
Run Code Online (Sandbox Code Playgroud)
如果isDebug == true,控制台中显示的行号和文件名将是正确的,因为etc 实际上是etcdebug.log的别名。console.log
如果isDebug == false,则不会显示任何调试消息,因为debug.logetc 根本不执行任何操作(空函数)。
如您所知,包装函数会弄乱行号和文件名,因此最好防止使用包装函数。
Chrome Devtools可让您通过Blackboxing实现这一目标.您可以创建可能有副作用的console.log包装器,调用其他函数等,并仍保留调用包装函数的行号.
只需将一个小的console.log包装器放入一个单独的文件中,例如
(function() {
var consolelog = console.log
console.log = function() {
// you may do something with side effects here.
// log to a remote server, whatever you want. here
// for example we append the log message to the DOM
var p = document.createElement('p')
var args = Array.prototype.slice.apply(arguments)
p.innerText = JSON.stringify(args)
document.body.appendChild(p)
// call the original console.log function
consolelog.apply(console,arguments)
}
})()
Run Code Online (Sandbox Code Playgroud)
将其命名为log-blackbox.js
然后转到Chrome Devtools设置并找到"Blackboxing"部分,为要黑盒子的文件名添加一个模式,在本例中为log-blackbox.js
Stack trace 解决方案显示行号但不允许单击转到源,这是一个主要问题。保持这种行为的唯一解决方案是绑定到原始函数。
绑定会阻止包含中间逻辑,因为此逻辑会与行号混淆。然而,通过重新定义绑定函数和使用控制台字符串替换,一些额外的行为仍然是可能的。
这个要点显示了一个简约的日志框架,它提供了模块、日志级别、格式和 34 行的正确可点击行号。将其用作满足您自己需求的基础或灵感。
var log = Logger.get("module").level(Logger.WARN);
log.error("An error has occured", errorObject);
log("Always show this.");
Run Code Online (Sandbox Code Playgroud)
编辑:下面包含的要点
var log = Logger.get("module").level(Logger.WARN);
log.error("An error has occured", errorObject);
log("Always show this.");
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
58019 次 |
| 最近记录: |