如何在JavaScript中正确覆盖console.warn

如何在JavaScript中正确覆盖console.warn,javascript,Javascript,我正在覆盖console.warn以捕获像这样打印到web浏览器控制台中的警告,我执行此操作的文件是track.js,如下所示。代码运行得非常好 文件1 // Filename - track.js function getWarnStatements() { window.warnStatements = []; var oldWarn = console.warn; console.warn = function (message) { oldWarn.apply(cons

我正在覆盖
console.warn
以捕获像这样打印到web浏览器控制台中的警告,我执行此操作的文件是
track.js
,如下所示。代码运行得非常好

文件1

// Filename - track.js

function getWarnStatements() {
  window.warnStatements = [];
  var oldWarn = console.warn;
  console.warn = function (message) {
  oldWarn.apply(console, arguments);
   window.warnStatements.push({
    type: 'console.warn',
    data: message,
   });  
 };
} 
文件2

// Filename - xyz.js

console.warn('Hello World');
假设我在另一个文件中使用了
console.warn()
,它是
xyz.js
,并且
track.js
xyz.js
同时运行。当我们通常检查浏览器控制台中的警告时,我们会在控制台中的警告右侧看到文件名,当我们单击文件名时,它会将我们带到写入
控制台.warn
的javascript文件

问题

检查下面的图片。它没有显示
xyz.js
,而是显示
track.js
。我怎样才能防止这种行为。我希望它将用户带到正确的文件,其中使用了
console.warn
,而不是我所使用的文件,因为这将导致误导其他开发人员使用错误的文件


从总体上看,问题在于拦截和捕获调用
控制台时提供的参数。warn
并完成在控制台上显示警告的意图,并指示警告在代码中出现的位置

首先,你不能躲在真正的
控制台前。警告打电话的地方,所以不要再耍花招,简化事情。剩下的两个选项是生成对替换的
warn
函数的调用的完整或部分跟踪

  • 完全跟踪

    在拦截的警告函数中,进行
    控制台.trace
    调用

  • 部分痕迹

    在intercepted warn函数中,创建一个新的错误对象,从对象的一行或多行切片,并将其记录到控制台,而不使用
    console.warn

  • 第二个选项的最大问题是,
    errorObject.stack
    在web标准中没有标准化-虽然您可以在尝试的浏览器中测试它并获得出色的结果(有细微的差异),但不能保证它在所有浏览器中都能工作

    总之,您实现的解决方案取决于用例-是用于内部测试,还是在web上,您需要在使用它们之前嗅探错误对象
    stack
    属性的存在

    作为补充说明,console.xxx函数接受多个参数,但发布的替代项不会记录这些参数


    下面是一个显示直接调用
    控制台.warn
    中间函数(帖子中匿名)的快速示例。要切片的行可能需要微调,如果表情符号不可接受,则根据需要替换:

    function interWarn(){
    设args=参数;
    //保存参数;
    设err=新错误(“跟踪”);
    var stack=err.stack;
    如果(!stack)尝试{
    犯错误;
    }
    捕捉(错误){
    stack=err.stack;
    }
    如果(堆栈){
    stack=stack.split('\n')。slice(1,3)。join('\n');
    
    控制台信息('⚠️ 来自文件
    xyz.js
    中\n%s\n%s',stack'的警告,尝试定义
    var$warn=console.warn;
    ,然后抛出警告:
    $warn('test'))
    。结果如何?@T–n尝试了它。仍然是一样的。问题是
    track.js
    是第一个运行的文件,所有其他有
    控制台.warns
    的文件都在它之后运行。有没有其他方法可以实现同样的效果,我是说捕获
    控制台.warn
    消息?非常感谢您的投资r回答时间到了。请编辑您的答案,并为
    控制台输入一个非常简短的示例。跟踪
    和部分跟踪。因为控制台中的完整跟踪太大,有些人无法阅读:)@MohammadBasit完成。该示例应返回到
    控制台。如果没有其他功能,则跟踪
    。显然,某些浏览器仅在抛出错误对象后向其添加(或添加)堆栈
    属性。