我可以在 javascript 中扩展控制台对象(用于重新路由日志记录)吗?
Posted
技术标签:
【中文标题】我可以在 javascript 中扩展控制台对象(用于重新路由日志记录)吗?【英文标题】:Can I extend the console object (for rerouting the logging) in javascript? 【发布时间】:2012-03-05 20:58:06 【问题描述】:是否可以扩展控制台对象?
我尝试了类似的方法:
Console.prototype.log = function(msg)
Console.prototype.log.call(msg);
alert(msg);
但这没有用。 我想通过 log4javascript 之类的框架向控制台对象添加额外的日志记录,并且在我的代码中仍然使用标准控制台对象(如果 log4javascript 不可用)。
提前致谢!
【问题讨论】:
为什么要扩展原型对象而不是扩展Console
对象本身?你有没有打电话给new Console()
?
【参考方案1】:
尝试以下操作:
(function()
var exLog = console.log;
console.log = function(msg)
exLog.apply(this, arguments);
alert(msg);
)()
【讨论】:
【参考方案2】:您也可以通过这种方式添加日志时间:
添加 Momentjs 或使用 New Date() 代替 moment。
var oldConsole = console.log;
console.log = function()
var timestamp = "[" + moment().format("YYYY-MM-DD HH:mm:ss:SSS") + "] ";
Array.prototype.unshift.call(arguments, timestamp);
oldConsole.apply(this, arguments);
;
【讨论】:
这不起作用,因为它会生成“未定义时刻”错误。 你必须使用 npm install moment 来安装 moment 好吧,我想,不过我更喜欢原生解决方案。例如,NPM 是需要存在的“另一个”东西【参考方案3】:这确实与其他人给出的解决方案相同,但我相信这是完成此任务的最优雅和最不笨拙的方法。扩展语法 (...args) 使 sure not a single argument is lost。
var _console=...console
console.log = function(...args)
var msg = ...args[0];
//YOUR_CODE
_console.log(...args);
【讨论】:
很好地使用了 spread/rest 语法,但它不是必需的,有一个小 1 行的方式支持 IE 并且不会覆盖上面的 protos。【参考方案4】:// console aliases and verbose logger - console doesnt prototype
var c = console;
c.l = c.log,
c.e = c.error,
c.v = c.verbose = function()
if (!myclass || !myclass.verbose) // verbose switch
return;
var args = Array.prototype.slice.call(arguments); // toArray
args.unshift('Verbose:');
c.l.apply(this, args); // log
;
// you can then do
var myclass = new myClass();
myclass.prototype.verbose = false;
// generally these calls would be inside your class
c.v('1 This will NOT log as verbose == false');
c.l('2 This will log');
myclass.verbose = true;
c.v('3 This will log');
我注意到上面 nitesh 对 Array.prototype.unshift.call 的使用是添加“详细:”标签的更好方法。
【讨论】:
【参考方案5】:适用于 ECMAScript 2015 及更高版本
您可以使用ECMAScript 2015 标准中较新的Proxy 功能来“劫持”全局console.log。
源代码
'use strict';
class Mocker
static mockConsoleLog()
Mocker.oldGlobalConsole = window.console;
window.console = new Proxy(window.console,
get(target, property)
if (property === 'log')
return function(...parameters)
Mocker.consoleLogReturnValue = parameters.join(' ');
return target[property];
);
static unmockConsoleLog()
window.console = Mocker.oldGlobalConsole;
Mocker.mockConsoleLog();
console.log('hello'); // nothing happens here
Mocker.unmockConsoleLog();
if (Mocker.consoleLogReturnValue === 'hello')
console.log('Hello world!'); // Hello world!
alert(Mocker.consoleLogReturnValue);
// anything you want to do with the console log return value here...
在线演示
Repl.it.
Node.js 用户...
...我不会忘记你。您可以获取此源代码并将window.console
替换为gloabl.console
以正确引用控制台对象(当然,摆脱alert
调用)。事实上,我最初编写了这段代码并在 Node.js 上进行了测试。
【讨论】:
与上面使用 6 行覆盖的答案相比,这是巨大的,我认为这对于简单的函数重写来说太过分了 不,不要使用代理劫持单个财产。【参考方案6】:您可以使用以下方法覆盖console.log
函数的默认行为,下面的示例演示使用覆盖的函数记录行号。
let line = 0;
const log = console.log;
console.log = (...data) => log(`$++line ===>`, ...data)
console.log(11, 1, 2)
console.log(11, 1, 'some')
【讨论】:
以上是关于我可以在 javascript 中扩展控制台对象(用于重新路由日志记录)吗?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Chrome 的 JavaScript 中覆盖/扩展 ReferenceError?