似乎其他语言支持Try / Catch,开发人员比使用JavaScript更多地使用该功能。是否有一个原因? Try / Catch的JS实现是否有缺陷?
答案 0 :(得分:35)
尝试看一下这篇文章:http://dev.opera.com/articles/view/efficient-javascript/?page=2#trycatch
从以上链接:
try-catch-finally结构非常独特。与其他构造不同,在运行时在当前作用域中创建一个新变量。这种情况发生每次执行catch子句,其中捕获的异常对象被分配给变量。即使在同一范围内,此变量也不存在于脚本的其他部分内。它在catch子句的开头创建,然后在它结束时销毁。
因为此变量是在运行时创建和销毁的,并且代表了该语言中的特殊情况,某些浏览器无法有效处理,并且将catch处理程序置于关键性能中在捕获异常时,循环可能会导致性能问题。
您还可以查看类似的问题here
<强>更新强>
添加一个链接到:https://github.com/petkaantonov/bluebird/wiki/Optimization-killers,因为它包含有关V8的有用信息以及它如何处理这些(和类似的)结构。
特别是:
目前无法优化:
可能永远不会优化:
答案 1 :(得分:12)
不,它没有缺陷,但对于同步代码,使用自己的代码检查事物通常比使用笨重的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";
};
答案 2 :(得分:9)
大多数javascript代码的异步性质将try / catch隐藏在较低级别,然后调用错误回调。
js中的大多数重型代码都是异步的,并使用回调或承诺模式。其他代码很简单,不需要try / catch。
如果你深入研究js库(选择你喜欢的),你会发现try / catch块包含了在现代js应用程序中执行的大量应用程序代码。然后,这些库会调用您在许多js代码示例中看到的错误或失败回调。
答案 3 :(得分:1)
我认为try / catch与if语句相比有更多的开销,尽管我认为只有在实际抛出异常时才有意义。我经常使用try / catches,但只有在我知道有可能抛出异常的情况下。
如果有效使用,则没有理由不使用try / catch。
答案 4 :(得分:0)
JavaScript并不需要它们,原因是,几乎没有任何理由可以捕获错误,因为一个错误并不能阻止整个脚本。 Javascript是事件驱动的,大多数函数在特定事件发生时运行,并且它是客户端,所以如果出现任何问题,它就会出错,捕获和处理错误几乎没有任何好处。 只有我的观点。