Override console.log (or any function in general): Is there a proper way to do this? [duplicate]

隐身守侯 提交于 2019-12-11 19:35:15

问题


I find myself doing this quite often both on the browser and in node.js and it's about time I came up with a proper way to do this without debugging it for a while each time.

Here's what I'm currently working on (this is 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));
};

This is basically a monkey patch to take console.logging code and turn it into proper logging code.

I'm not sure if this is something proper or completely asinine.

Conceptually, I am forcing arguments sent to console.log into an array, which then is passed to apply. All of this is to work around the fact that I don't know how to declare a variadic function in JS. (perhaps this is the canonical way to do so).

Perhaps the same can be achieved with console.log = logger.debug. Oh well, I want to know how I can pass the arguments.

For instance, there are certain things of this sort that won't work for whatever reason in the browser (but does in node):

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

Granted, this is not the same as overriding console.log, this is just to shorten the name of it, but still.

Ah, I actually realized what's wrong here: This will work.

l.call(console, 'hello');

Which means it's just missing a bit of finagling with this.

If you are still looking for the actual question of this question look at the italicized line above.


回答1:


I'm not sure if this is something proper or completely asinine.

For your own projects, it should be fine. Though, I would probably refrain from modifying Node's documented API (beyond the few parts that suggest modification) for any projects you intend to distribute on NPM.


Currently, .apply() is the only way to specify a collection as the arguments to a function call.

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

Though, ECMAScript 6 will be introducing the spread operator as an alternative.

logger.debug(...arguments);

However, the slice probably isn't necessary, since it isn't modifying the collection before passing it.

logger.debug.apply(logger, arguments);

As for l('hello'), you can use .bind() to ensure the context.

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

Though, this does depend on what version of a particular engine you're using. With Node 0.10.15 and Chrome 28, console.log is already bound to console. So, the snippet you listed wouldn't throw an error.



来源:https://stackoverflow.com/questions/18050744/override-console-log-or-any-function-in-general-is-there-a-proper-way-to-do-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!