覆盖console.log(或一般的任何功能):有没有正确的方法来执行此操作?

时间:2013-08-05 04:47:52

标签: javascript node.js logging log4javascript

我发现自己在浏览器和node.js中都经常这样做,而且这时候我想出了一个正确的方法来做这个,而不是每次都调试一段时间。

以下是我目前正在处理的内容(这是node.js):

var log4js = require("log4js");

log4js.loadAppender('file');
log4js.addAppender(log4js.appenders.file('log.log'));
var logger = log4js.getLogger();
console.log = function () {
    logger.debug.apply(logger, Array.prototype.slice.call(arguments));
};

这基本上是一个猴子补丁,用于获取console.log ging代码并将其转换为正确的日志代码。

我不确定这是不是正确或完全是asinine。

从概念上讲,我强制将发送到console.log的参数转换为数组,然后传递给apply。所有这些都是为了解决这个事实,即我不知道如何在JS中声明一个可变参数函数。 (也许这是规范的方式)。

使用console.log = logger.debug也许可以达到同样的效果。哦,我想知道如何传递参数。

例如,某些事情在浏览器中出于某种原因无效(但在节点中):

var l = console.log;
l('hello');

enter image description here

当然,这与覆盖console.log不同,这只是为了缩短它的名称,但仍然如此。

啊,我实际上意识到这里有什么问题:这会有用。

l.call(console, 'hello');

这意味着它只是遗漏了this的一些问题。

如果您仍在寻找此问题的实际问题,请查看上面的斜体。

1 个答案:

答案 0 :(得分:2)

  

我不确定这是不是正确或完全as。

对于你自己的项目,应该没问题。但是,对于您打算在NPM上分发的任何项目,我可能会避免修改Node的文档化API(超出建议修改的几个部分)。


目前,.apply()是指定集合作为函数调用参数的唯一方法。

logger.debug.apply(logger, Array.prototype.slice.call(arguments));

虽然,ECMAScript 6将引入spread operator作为替代。

logger.debug(...arguments);

但是,slice可能不是必需的,因为它在传递之前不会修改集合。

logger.debug.apply(logger, arguments);

对于l('hello'),您可以使用.bind()来确保上下文。

var l = console.log.bind(console);
l('hello');

但是,这取决于您使用的特定引擎的版本。使用Node 0.10.15和Chrome 28,console.log已绑定到console。因此,您列出的代码段不会引发错误。