【问题标题】:Which of these cross-browser Javascript functions performs better?这些跨浏览器 Javascript 函数中哪一个性能更好?
【发布时间】:2009-03-12 01:56:55
【问题描述】:

根据经验,这些编写跨浏览器 Javascript 函数的方法中哪一种性能更好?

方法一

function MyFunction() 
{
    if (document.browserSpecificProperty)
       doSomethingWith(document.browserSpecificProperty);
    else
       doSomethingWith(document.someOtherProperty);
}

方法二

var MyFunction;
if(document.browserSpecificProperty) {
    MyFunction = function() {
       doSomethingWith(document.browserSpecificProperty);
    };
} else {
    MyFunction = function() {
       doSomethingWith(document.someOtherProperty);
    };
}

编辑: 为迄今为止所有好的答案投票。我已将函数修复为更正确的语法。

到目前为止,关于答案的几点说明 - 虽然在大多数情况下,这是一种相当没有意义的性能增强,但仍有一些原因可能需要花一些时间分析代码:

  • 必须继续运行 慢速电脑、移动设备、旧 浏览器等。
  • 好奇心
  • 使用相同的 绩效的一般原则 增强其他场景 IF 语句的评估确实 需要一些时间。

【问题讨论】:

  • 唉,这实际上不是跨浏览器代码,因为它依赖于仅在 mozilla 中出现的行为。

标签: javascript performance cross-browser


【解决方案1】:

除非你这样做一万亿次,否则没关系。选择对您和/或您的组织更具可读性和可维护性的版本。编写干净、简单的代码所带来的生产力提升比将 JS 执行时间缩短十分之一微秒更重要。

您甚至应该只开始思考什么性能更好当且仅当您编写了代码并且速度慢得令人无法接受。然后你应该开始追踪瓶颈,这永远不会是这样的。在这里从一个切换到另一个,您永远不会获得可衡量的性能提升。

【讨论】:

    【解决方案2】:

    不幸的是,上面的代码实际上并不是跨浏览器友好的,因为它依赖于其他浏览器中不存在的 mozilla 怪癖——即 function statements 被视为 function 分支内的表达式。在非 Mozilla 上构建的其他浏览器上,上述代码将始终使用第二个函数定义。我做了一个简单的测试用例来演示这个here

    基本上,ECMAScript 规范说函数语句的处理方式与 var 声明类似,例如。它们都被提升到当前执行范围的顶部(例如

    【讨论】:

      【解决方案3】:

      为了澄清 olliej 的答案,您的第二种方法在技术上是语法错误。你可以这样重写:

      var MyFunction;
      if(document.browserSpecificProperty) {
          MyFunction = function() {
             doSomethingWith(document.browserSpecificProperty);
          };
      } else {
          MyFunction = function() {
             doSomethingWith(document.someOtherProperty);
          };
      }
      

      这至少是正确的语法,但请注意 MyFunction 仅在发生这种情况的范围内可用。 (省略var MyFunction;,全局最好使用window.MyFunction = function() ...。)

      【讨论】:

      • 其实不是语法错误,是完全有效的js,只是不太可能做你想做的事。这很像 var 行为,因为人们希望 js 对 var 使用语法范围,但实际上它只是函数的范围。
      • 据我了解,其实是语法错误。也许我的理解是错误的。我将不得不重新阅读规范的相关部分,不幸的是我现在不能。我将删除我的那部分答案。
      • 我会重新检查规范——我知道所有的 JS 引擎都会解析它,所以它可能已经成为事实上的语法,即使它没有做想要的。
      • 啊哈,你是对的,根据规范,这将是一个解析错误,因为 FunctionDeclaration 产生只发生在 SourceElement 产生而不是语句中。所以我很抱歉你是对的——这在技术上是一个语法错误。
      • 回滚。我记得读过一篇对 Prototype 的批评,其中将其描述为语法错误,因此我在规范中查找了它并得出结论认为它们是正确的(在那一点上)。但是我对规范的实际记忆已经消失了。感谢您在我回到它之前进行检查。 :)
      【解决方案4】:

      从技术上讲,我会说第二个会执行得更好,因为 if 语句只执行一次,而不是每次运行函数时。

      但是,差异可以忽略不计,甚至毫无意义。即使与简单地调用函数的性能损失相比,像这样的单个 if 语句的性能损失也微不足道。即使被调用一百万次,它也会产生微小的差异。

      第一个更容易理解,因为它没有根据条件两次定义相同函数的尴尬,两个版本的行为不同。这似乎是后来混淆的秘诀。

      我不会是第一个这么说的人,除非你真的对这个优化很疯狂,否则你会从代码可读性中获得更多的胜利。

      【讨论】:

      • 不知道为什么会有如此多的反对票 - 如果您认为我错了,请解释原因。
      【解决方案5】:

      我通常更喜欢第二个版本,因为条件只需要评估一次,而不是每次调用,但有时它并不真正可行,因为它会妨碍可读性。

      顺便说一句,在这种情况下,您可能想要使用 ?: 运算符,例如(取自生产代码):

      var addEvent =
          document.addEventListener ? function(type, listener) {
              document.addEventListener(type, listener, false);
          } :
          document.attachEvent ? function(type, listener) {
              document.attachEvent('on' + type, listener);
          } :
          throwError;
      

      【讨论】:

        【解决方案6】:

        对于您的简化示例,假设您的浏览器属性检查只需要执行一次,我将执行以下操作:

        var MyFunction = (function() {
        
              var rightProperty = document.browserSpecificProperty || document.someOtherProperty;
        
              return function doSomethingWith() {
                    // use the rightProperty variable in your function
              }
        })();
        

        【讨论】:

          【解决方案7】:

          性能应该差不多!

          关于使用像 JQuery 这样的框架来摆脱浏览器兼容性问题的事情!

          如果性能是您的主要目标,请查看SlickSpeed!这是一个对不同 JavaScript 框架进行基准测试的页面!

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-09-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-30
            • 2011-02-06
            • 2021-04-03
            • 1970-01-01
            相关资源
            最近更新 更多