似乎对于支持 Try/Catch 的其他语言,开发人员比在 JavaScript 中更多地使用该功能。是否有一个原因?Try/Catch 的 JS 实现是否有缺陷?
5 回答
试着看看这篇文章:http ://dev.opera.com/articles/view/efficient-javascript/?page=2#trycatch
从上面的链接:
try-catch-finally 结构相当独特。与其他构造不同,它在运行时在当前范围内创建一个新变量。每次执行 catch 子句时都会发生这种情况,其中捕获的异常对象被分配给一个变量。即使在同一范围内,此变量也不存在于脚本的其他部分中。它在 catch 子句的开头被创建,然后在它的结尾被销毁。
因为这个变量是在运行时创建和销毁的,并且代表了语言中的一种特殊情况,所以一些浏览器不能非常有效地处理它,并且在性能关键循环中放置一个 catch 处理程序可能会在捕获异常时导致性能问题。
您也可以在这里查看类似的问题
更新
添加指向:https ://github.com/petkaantonov/bluebird/wiki/Optimization-killers 的链接,因为它包含有关 V8 以及它如何处理这些(和类似)构造的有用信息。
尤其:
目前不可优化:
- 生成器函数
- 包含 for-of 语句的函数
- 包含 try-catch 语句的函数
- 包含 try-finally 语句的函数
- 包含复合 let 赋值的函数
- 包含复合 const 赋值的函数
- 包含包含proto或 get 或 set 声明的对象文字的函数。
可能永远无法优化:
- 包含调试器语句的函数
- 逐字调用 eval() 的函数
- 包含 with 语句的函数
不,它没有缺陷,但是对于同步代码,使用自己的代码检查事情通常比使用笨重的try{}catch(e){}
.
例子:
var container = document.getElementById("timmy");
container.innerHTML = "I'm timmy!";
如果没有 ID 为“timmy”的元素,我们可以这样处理:
try
{
container.innerHTML = "I'm timmy";
}
catch (error)
{
//handle no container
}
或者:
if(container) container.innerHTML = "I'm timmy";
else //handle no container
要记住的另一件事是 JavaScript 应用程序是事件驱动的,程序主体中的 try/catch 块无法捕获事件回调中发生的错误。
例子:
sqlConnection.query("SELECT * FROM table",
function(){console.log("queried!");});
这将触发一些在您的程序继续运行时运行的本机代码。如果发生错误,您不能期望您的程序回溯到这一行,以便您的错误处理程序可以完成它的工作!相反,您在回调本身中处理错误。通常的做法是通过将发生的任何错误作为第一个参数传递来提供回调。
sqlConnection.query("SELECT * FROM table",
function(error, data){
if(error) console.log("query failed");
else console.log("queried!");
});
或者,如果您的代码在回调中失败,您可以按照我上面提到的方式处理它。
link.onclick = function(e)
{
var popUp = document.getElementById("popup");
if(!popUp)
return true; //follow link if no pop-up exists
popUp.style.display = "block";
};
大多数 javascript 代码的异步特性将 try/catch 隐藏在低级别,然后调用错误回调。
js 中最繁重的代码是异步的,并使用回调或承诺模式。其他代码很简单,不需要 try/catch。
如果你深入研究 js 库(选择你最喜欢的),你会发现 try/catch 块包装了现代 js 应用程序中执行的大量繁重的应用程序代码。然后这些库调用您在许多 js 代码示例中看到的错误或失败回调。
我相信与 if 语句相比,try/catch 的开销更大,尽管我认为只有在实际抛出异常时才重要。我经常使用 try/catch,但前提是我知道很有可能会抛出异常。
如果有效地使用,真的没有理由不使用 try/catch。
JavaScript 不太需要它们,原因是,几乎没有任何理由去捕捉错误,因为,一个错误不会停止整个脚本。Javascript 是事件驱动的,大多数函数在特定事件发生时运行,并且它是客户端,所以如果出现任何问题,它就会出错,捕获和处理错误几乎没有任何好处。只有我的看法。