是否将一个函数赋值给window.onerror,而不是window.addEventListener('error',callback)?

Ala*_*lan 14 javascript error-handling

分配函数window.onerror似乎是一种非常直接的方式来开始处理页面上的代码中的错误.但是,确保不覆盖预先存在的错误处理程序非常重要,因此通常的做法是保持对先前值的引用并将其作为新函数的一部分进行调用.举个例子:

var old_onerror = window.onerror;
window.onerror = function() {
    // do something
    if (old_onerror) {
        old_onerror();
    }
};
Run Code Online (Sandbox Code Playgroud)

我可以在网上找到的大多数文档/博客文章/等建议做这样的事情.他们为什么不建议为事件添加事件处理程序'error'呢?这允许在触发其中一个事件时调用多个函数,并且不需要笨拙地维护对其他错误处理程序的引用.

window.addEventListener('error', function() {/* do something */});
Run Code Online (Sandbox Code Playgroud)

编辑:我考虑过遵循关于这个主题的标准建议,但error事件window似乎是一个相当特殊的情况(例如,参见JQuery 显然缺乏对它的支持(在该页面上搜索"onerror")).我特意寻求洞察为什么onerror似乎是一个特例.

Kei*_*ith 7

由于历史原因,这window.onerror有些特殊情况。现在大多数这些功能已经失效,我认为您必须回到IE8才能找到需要它们的浏览器。大约十年前,IE6是王者,它根本不支持addEventListener,许多事件仅受某些浏览器支持或使用不同的名称。Web开发以前一直是前后矛盾的,找到像这样的旧方法也很常见window.onerror

出于向后兼容性的原因window.onerror,有些奇怪之处在于,订阅事件的两种方式采用了不同的论点。

因此,旧版onerror包含错误详细信息作为参数:

window.onerror = function(message, source, line, col, error) {
    ...

    return true; // This will prevent further event propagation
};
Run Code Online (Sandbox Code Playgroud)

它仍然存在,以便已经存在的旧JS不会崩溃-浏览器设计师希望拥有10年历史的网站仍基本上可以在其最新版本中工作。

尽管(现在是最佳实践)事件侦听器将它们作为事件的属性:

window.addEventListener('error', e => {

    // Get the error properties from the error event object
    const { message, source, lineno, colno, error } = e; 
});
Run Code Online (Sandbox Code Playgroud)

后者要好得多,因为您不需要获取任何先前的侦听器,并且以后的侦听器(例如来自浏览器扩展程序)都不会意外破坏您的侦听器。此外,如果您要构建的SPA之类的内容停留在一页上且具有一个window上下文,则可以删除您的侦听器。

所以,要回答这个问题:

我可以在网上找到的大多数文档/博客文章/等建议这样做。他们为什么不建议改为为“错误”事件添加事件处理程序?

因为他们已经过时了。使文档保持最新是很困难的,并且JS动作很快。window.onerror您描述的 模式在某些公司环境中仍然是可以接受的折衷方案,在这些公司环境中需要支持IE的过时版本。对于绝大多数网络而言,该addEventListener方法要好得多。

例如,请参见JQuery明显缺乏对它的支持(在该页面上搜索“ onerror”

jQuery很老了。在2006年至2008年间做出了一些决定,以至于现在它永远存在,而.on做出事件的一些假设就是其中之一。jQuery .on在2006年很棒,因为我们不必担心不同浏览器的事件实现-它可以将所有浏览器都隐藏在一个通用界面后面。现在,所有内容都会使用,addEventListener因此您不需要它(它比强大得多.on)。