javascript 中 console.log 的实际拦截器

Ali*_*orm 5 javascript

对于 js console.log 拦截器的通常建议(Capturing javascript console.log?)在两个方面都存在不足,都很严重:

(i) 实际浏览器控制台中的所有调用现在似乎都来自同一行——定义新函数的地方——而不是调用完成的地方

(ii) 截取的参数还没有像这样格式化console.log(即%替换好东西,%o特别是):

(function() {
  function send_stuff(){ /* Deal with console arguments. */ }
  
  var oldLog=console.log;
  console.log=function(msg) {
    oldLog.apply(this,arguments);
    send_stuff(Array.prototype.slice.call(arguments).join());
  }
}())

console.log("test");
console.log("Hello %s", "Bob");
console.log("Here is an object %o", { stuff: "thing" });
Run Code Online (Sandbox Code Playgroud)

也许已经设计了更好的东西(例如能够捕获 console.log 的实际缓冲区内容的东西)。

编辑: 为了澄清多个参数失败:除了扩展文件/行信息之外,console.log 还做了一些巧妙的替换 - a-la-printf - % 序列。特别有趣的是 %o 序列,其中扩展了后续对象的深度转储,并被浏览器的控制台窗口很好地利用。这是无法复制的,除非人们愿意基本上重新实现其逻辑(不必要并且很可能效率低下)

干杯,

Wat*_*oll -1

看起来行为发生了console.log一些变化,现在遮罩正在工作,但您仍然oldLog.apply(this,arguments);在控制台中收到该行。您可以做的一件事就是使用console.error它,这将显示调用堆栈,您可以使用它来查看最初调用修改后的日志方法的行。

另一种解决方案是抛出错误以从调用堆栈中获取行号,如下所示

(function () {

  function origin() {
    try {
      throw Error('');
    } catch (err) {
      return err.stack.split('\n').slice(-1)[0];
    }
  }

  function send_stuff() { /* Deal with console arguments. */ }

  var oldLog = console.log;
  console.log = function (msg) {
    oldLog.call(this, ...arguments, origin());
    send_stuff(Array.prototype.slice.call(arguments).join());
  };

})();

console.log("test");
console.log("Hello %s", "Bob");
console.log("Here is an object %o", {
  stuff: "thing"
});
Run Code Online (Sandbox Code Playgroud)