为什么Try/Catch在JavaScript中不经常使用?

Dar*_*don 36 javascript

看起来其他语言支持Try/Catch,开发人员比JavaScript更多地使用该功能.是否有一个原因?Try/Catch的JS实现有缺陷吗?

Cha*_*ase 35

试着看一下这篇文章:http://dev.opera.com/articles/view/efficient-javascript/?page = 2#trycatch

从以上链接:

try-catch-finally结构非常独特.与其他构造不同,它在运行时在当前作用域中创建一个新变量.每次执行catch子句时都会发生这种情况,其中捕获的异常对象被分配给变量.即使在同一范围内,此变量也不存在于脚本的其他部分内.它在catch子句的开头创建,然后在它结束时销毁.

因为此变量是在运行时创建和销毁的,并且代表了该语言中的特殊情况,所以某些浏览器无法非常有效地处理它,并且在捕获异常时将陷阱处理程序置于性能关键循环中可能会导致性能问题.

您还可以在此处查看类似的问题

UPDATE

添加链接到:https://github.com/petkaantonov/bluebird/wiki/Optimization-killers,因为它包含有关V8的有用信息以及它如何处理这些(和类似的)构造.

特别是:

目前无法优化:

  • 发电机功能
  • 包含for-of语句的函数
  • 包含try-catch语句的函数
  • 包含try-finally语句的函数
  • 包含复合的函数允许赋值
  • 包含复合const赋值的函数
  • 包含包含proto或get或set声明的对象文字的函数.

可能永远不会优化:

  • 包含调试器语句的函数
  • 字面上调用eval()的函数
  • 包含with语句的函数

  • 更糟糕的是(从性能角度来看)V8至少不会用try-catch优化函数.因此,即使整个循环发生在try块内,它也会变慢.仅仅通过在其自身功能中移动性能关键循环并将try-catch保持在其外部,我在一次测试中将性能提高了大约10-15%. (4认同)
  • 更新:根据https://github.com/petkaantonov/bluebird/wiki/Optimization-killers,除了第一个和最后一个"当前不可优化"的构造外,所有构造现在都是可以优化的. (3认同)

Mic*_*nXD 13

不,它没有缺陷,但对于同步代码,使用自己的代码检查事物通常比使用笨重更容易和更干净try{}catch(e){}.

例:

var container = document.getElementById("timmy");
container.innerHTML = "I'm timmy!";
Run Code Online (Sandbox Code Playgroud)

如果没有ID为"timmy"的元素,我们可以像这样处理:

try
{
    container.innerHTML = "I'm timmy";
}
catch (error)
{
    //handle no container
}
Run Code Online (Sandbox Code Playgroud)

要么:

if(container) container.innerHTML = "I'm timmy";
else //handle no container
Run Code Online (Sandbox Code Playgroud)

另外要记住的是JavaScript应用程序是事件驱动的,并且程序主要部分中的try/catch块无法捕获事件回调中发生的错误.

例:

sqlConnection.query("SELECT * FROM table", 
    function(){console.log("queried!");});
Run Code Online (Sandbox Code Playgroud)

这将触发一些在程序继续时运行的本机代码.如果发生错误,您不能指望您的程序回溯到此行,以便您的错误处理程序可以执行其操作!相反,您在回调本身处理错误.通常的做法是通过将回调作为第一个参数传递给回调发生任何错误.

sqlConnection.query("SELECT * FROM table", 
    function(error, data){
        if(error) console.log("query failed");
        else console.log("queried!");
    });
Run Code Online (Sandbox Code Playgroud)

或者,如果您的代码在回调中失败,您可以按照我上面提到的方式处理它.

link.onclick = function(e)
{
    var popUp = document.getElementById("popup");
    if(!popUp)
        return true; //follow link if no pop-up exists
    popUp.style.display = "block";
};
Run Code Online (Sandbox Code Playgroud)

  • 如果,*通过一些测试*,您可以确保异常不会发生,那么就不需要 try catch。在 Javascript 中只有少数情况需要测试/探测错误。 (2认同)

Sru*_*uly 9

大多数JavaScript代码的异步性质将try/catch隐藏在较低级别,然后调用错误回调.

js中最重要的代码是异步并使用回调或承诺模式.其他代码很简单,不需要try/catch.

如果你深入研究js库(选择你喜欢的),你会发现try/catch块包含了在现代js应用程序中执行的大量应用程序代码.然后,这些库会调用您在许多js代码示例中看到的错误或失败回调.