7

问题

不敢相信我在网上找不到任何东西,也许我正在寻找错误的东西......

可能几乎没有区别,但是当我尽可能地优化我的代码时,我觉得值得一问。

很简单,我想知道在对象中定义和运行方法是否比全局定义和运行函数更快。

例子

考虑一下:

(function($){  
    $.fn.test = function() {  
        // do something here
    };  
})(jQuery);

还有这个:

function test(){
    // do something here
}

我的问题

以上哪个更快,为什么?如果速度没有差异,那么您建议使用哪个?

提前致谢

更新 1

由于它可能是相关的,我觉得有必要解释我为什么要问这个问题。我有一个多年来编写的库,其中包含多种功能。因为它们太多了,我想知道如果我要扩展 jQuery 对象,它们是否会运行得更快,或者保持它们原样?

4

3 回答 3

7

理论上,您只需要计算必须搜索的对象的数量即可确定哪个更快。变量是根据作用域链解析的,脚本引擎必须首先搜索函数的执行上下文,然后是外部上下文,最后是全局上下文。

属性解析必须首先找到作用域链上的对象,然后是对象或其[[Prototype]]链上的属性。

但在实践中,编译器优化意味着上述简单化的分析是错误的,也是正确的,并且在不同的浏览器中针对不同的情况提供不同的结果。

通常,此类优化会带来微小的性能变化,不应仅出于性能原因考虑。为您的应用程序架构、易于维护和逻辑分组设计任何有意义的对象和方法。

于 2012-10-25T08:21:59.847 回答
3

我大约一年前做过这项研究,我可以说它使用起来更快this.test()

但这取决于你需要什么。如果您只想为特定的“小部件”创建一个对象,我不建议向 jQuery 添加不必要的函数。

简单的面向对象用法:

function Car(name) {
    this.name = name;
}

Car.prototype.startEngine = function() {
    // Start the engine...
};

Car.prototype.drive = function() {
    this.startEngine();

    // Switch the lights, fasten your seatbelt...
};


// create a new car
var bmw = new Car('BMW');

// Drive the car
bmw.drive();

您必须了解的另一件事是环境(我希望您理解我的意思)。最好为变量和函数创造一个新鲜的空间,这样就没有太多的变量/函数需要寻找。把它想象成一个列表——如果它更小,在其中找到东西会更快。所以,你创造了一个新的“空间”:

(function(){
    // Your fresh space.
})();

JavaScript 将尝试在“本地”空间中查找内容,然后尝试在全局空间中查找内容。想象它是这样的:

|- global
     |- function aaa
     |- function bbb
     |- var myName
     |- your local space
           |- function ccc
           |- function aaa  It will not overwrite global function with the same name
           |- var someVariable

如您所见,在“本地空间”中只有 3 个项目,因此查找内容更快。

在本地“空间”中调用半全局函数更快。而且,如果你想做一些面向对象的东西,扩展“对象”会更好更快。

更新 如果你想整理你的函数库,那么你可以将它们分组到一个对象中。我不认为它会更慢。

var lib = {
    foo: function() {},
    bar: function() {},
    test: function() {}
};

lib.test();
于 2012-10-25T08:21:29.470 回答
2

当您想知道两种方法中哪一种更快时,最好的方法是分析它们。这将为您提供与您的代码相关的结果,而不是一个通用概念。

在我看来,你不应该为了速度而优化它,而是为了 API 的可维护性和丰富性。从你的问题

function test(){
    // do something here
}

在全局范围内,这总是很糟糕。理想情况下,您应该将这些方法放在命名空间中,并且问题中的示例 1 将其作为 jQuery 命名空间的一部分。

于 2012-10-25T08:23:18.570 回答