在JavaScript中覆盖console.log

时间:2016-02-22 07:35:04

标签: javascript override console.log

我希望覆盖console.log方法,以便在调用console.log时调用一组任务。我提到了其他Stackoverflow的答案,但这给了我错误:

  

未捕获RangeError:超出最大调用堆栈大小。

这就是我想要做的事情:

backupconsolelog = console.log;

console.log = function(arguments)
{
    //do my tasks;

    backupconsolelog(arguments);
}

更新1 :以某种方式设法成功覆盖了console.log,但我现在无法在完成覆盖的同一.js文件中执行console.log(displaySomethingInConsole)。这会以某种方式导致递归调用console.log,并再次提供Uncaught RangeError: Maximum call stack size exceeded.

如何在同一个.js文件中使用console.log()?

更新2 :我有一个check()函数,由过度使用的console.log调用。但是,console.log函数内部发出了check()次调用,导致Maximum call stack size exceeded.错误。

更新3 :再次出错! :(

  

未捕获的TypeError:非法调用

var _log = window.console.log;
window.console.log = function () {
_log.apply(this, arguments);
check();
};

_log("aaa");
check() {};

更新4 Binding console_log,即console.log.bind(console)已将其清除。

6 个答案:

答案 0 :(得分:3)

如果您的最大调用堆栈大小超出错误,则几乎肯定意味着您的功能是 recursively calling itself infinitely 。您找到的解决方案以及 RaraituL 所显示的解决方案应该可以正常运行。您可能正在调用代码中不止一次设置调用重定向的部分。

// First time:
backupconsolelog = console.log.bind(console);
console.log = function() {
    backupconsolelog.apply(this, arguments);
    /* Do other stuff */
}
// console.log is now redirected correctly

// Second time:
backupconsolelog = console.log;
// Congratulations, you now have infinite recursion

您可以添加一些调试信息(不使用console.log,显然,请尝试debugger;来创建自动断点),您可以在其中设置重定向以查看位置和当你的代码被调用时。

<强>更新

这可能属于注释:您的console.log重定向函数显然会调用一些名为check的函数。然后,此check函数会调用console.log,如果您的函数 - 则不是原始函数。让check函数调用原始实现。

backupconsolelog = console.log.bind(console);

console.log = function() {
    check();
    backupconsolelog.apply(this, arguments);
}

function check() {
    // This will call your function above, so don't do it!
    console.log('Foo');

    // Instead call the browser's original implementation:
    backupconsolelog('Foo');
}

更新2

浏览器console.log实施的内部工作方式可能会或可能不会取决于为console引用设置的this。因此,您应将console.log 绑定存储到console,就像我的代码一样。

答案 1 :(得分:2)

// keep reference to original function
var _log = window.console.log;

// overwrite function
window.console.log = function () {
    _log.apply(this, arguments);
    alert(arguments);
};

console.log("hello world");

答案 2 :(得分:0)

您可能需要将原始方法绑定到控制台:

var old = console.log.bind(console)
console.log = (...args) => {
  // perform task
  alert('test')
  old.apply(null, args)
}

答案 3 :(得分:0)

在遇到一些问题之后,我设法用winston + express替换了console.log。

我使用winston-sugar,因为它使配置更容易,但任何方法都可以。 (当您执行npm install winston-sugar时会创建.config / winston.json) 希望用其他内容替换console.log的人们可以只看最后5行,因为它提供了非常干净的代码。

我认为这是使Express与console.log一起登录文件的一种非常简洁的方法

const morgan = require('morgan');
const winstonLoader = require('winston-sugar');
winstonLoader.config('./config/winston.json');
const log = winstonLoader.getLogger('app');
log.stream = {
  write: function (message, encoding) {
    log.info(message);
  },
};

// Add some lines indicating that the program started to track restarts.
log.info('----------------------------------');
log.info('--');
log.info('-- Starting program');
log.info('--');
log.info('----------------------------------');

console.log = (...args) => log.info(...args);
console.info = (...args) => log.info(...args);
console.warn = (...args) => log.warn(...args);
console.error = (...args) => log.error(...args);
console.debug = (...args) => log.debug(...args);

如果您正在运行Express,则在代码后面。

// app.use(morgan('combined')); //replaced with the next line to get morgan logs into the winston logfiles.
app.use(morgan('combined', { stream: log.stream }));

答案 4 :(得分:0)

这对我有用。

let originalConsole = Object.assign({}, console);
console.log = (value) => {
    //some cool condition
    if (true) {
        value = "new_log : " + value
    }
    originalConsole.log(value);
};

答案 5 :(得分:0)

接受的答案将适用于提供的结构,除非您需要在运行的实例上多次“设置”覆盖。如果您有一个实时容器或 lambda 函数,您将面临参数数组自行构建的风险。

[ arg1 ] -> [ [arg1] , arg2 ] -> [ [ [ arg1 ] , arg2] , arg3 ] 

例如:

function x(){
  var log = console.log;
  console.log = function () {
        var args = Array.from(arguments);
        args.push('post fix');
        log.apply(console, args);
    }
}

new x()
console.log(1)
new x()
console.log(2)

OUTPUTS:
1 post fix
2 post fix post fix

解决方案:

确定您是否需要将此功能用作中间件,例如, 您在中间件功能之外维护引用,例如:

var log = console.log;
function x(){
  console.log = function () {
        var args = Array.from(arguments);
        args.push('post fix');
        log.apply(console, args);
    }
}

new x()
console.log(1)
new x()
console.log(2)

OUTPUTS: 
1 post fix
2 post fix

或者更好...

const log = console.log;
function middleWare() {
    console.log = (...args) => {
        log(...args, 'post fix');
    }
}