Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

try语句的正确使用方法

  获取程序运行时候的错误信息对于许多编译型语言来说本身就是一个耗时的操作,所以我们往往认为获取错误信息是需要一部分性能开销的。但脚本语言不同,它运行时本身就会产生详细的错误信息,不像C++之类的程序运行时错误只能给出一串内存地址。
  实际上脚本语言中获取错误信息并不造成额外的性能开销,只是把原本应该输出到控制台的东西输出到其它地方罢了。但很多时候,我们在代码中使用try语句做测试时确实影响了性能。这是因为try语句本身破坏了所在作用域中的一些优化。这可以从它对Firefox的影响效果中得到证实。Firefox本身就不优化,所以在Firefox中,任凭你怎么“踹”它都不会影响它的性能。
  但是对于Chrome和IE这些使用高优化JavaScript引擎的浏览器来说,破坏优化就是个大问题。可以做这样的测试
<input type="button" value="直接执行" id="test1" />
<input type="button" value="try语句中执行" id="test2" />
<input type="button" value="try语句中函数执行" id="test3" />
<script>
test1.onclick=function(){
  console.time(this.value);
  for(var i=0;i<1E8;i++);
  console.timeEnd(this.value);
};
test2.onclick=function(){
  try{
    console.time(this.value);
    for(var i=0;i<1E8;i++);
    console.timeEnd(this.value);
  }catch(e){};
};
test3.onclick=function(){
  try{
    (function(){
      console.time(this.value);
      for(var i=0;i<1E8;i++);
      console.timeEnd(this.value);
    }).call(this);
  }catch(e){};
};
</script>

  这个测试就可以看出,获取错误信息的这个功能本身并不会影响性能,只是try语句的存在本身影响了其所在作用域的优化而已。只要让代码不和try语句呆在同一个作用域下就不会受其影响。而且,虽说try语句会影响作用域的优化,但比起局部eval的影响要小的多。局部eval会坑爹坑长辈,整个作用域链的性能都会受到拖累,而try只影响自己所在的作用域,不会影响到父作用域或子作用域。
<input type="button" value="自作用域存在try语句" id="test1" />
<input type="button" value="子作用域存在try语句" id="test2" />
<input type="button" value="父作用域存在try语句" id="test3" />
<script>
test1.onclick=function(){
  try{}catch(e){};
  console.time(this.value);
  for(var i=0;i<1E8;i++);
  console.timeEnd(this.value);
};
test2.onclick=function(){
  (function(){
    try{}catch(e){};
  })();
  console.time(this.value);
  for(var i=0;i<1E8;i++);
  console.timeEnd(this.value);
};
test3.onclick=function(){
  try{}catch(e){};
  (function(){
    console.time(this.value);
    for(var i=0;i<1E8;i++);
    console.timeEnd(this.value);
  }).call(this);
};
</script>

  所以可以大胆地使用try语句,只要注意关键代码不和它呆在同一作用域即可。

  测试于:
    Chrome 31.0.1650.63 m
    Firefox 26.0
    IE 11.0.9600.16476
网名:
3.80.55.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^