我应该将 jQuery 或 DOM 对象作为参数传递吗? (性能问题)

Posted

技术标签:

【中文标题】我应该将 jQuery 或 DOM 对象作为参数传递吗? (性能问题)【英文标题】:Should I pass a jQuery or DOM object as arguments? (Performance Question) 【发布时间】:2011-11-24 06:04:55 【问题描述】:

哪个性能更好。

foo(this);

function foo(element) 

    $(element).index();


或者我应该这样做

foo($(this));

function foo($element) 

    $element.index();


显然考虑到我将在函数中多次使用该参数。

谢谢! 康纳

【问题讨论】:

【参考方案1】:

如果你要包装一个对象,你在 jQuery 上包装一个对象的位置并不重要。

只需要缓存包装结果并且不要包装两次。

就此而言,以下规则适用于许多插件的代码:

1) jQuery 变量都以 $ 为前缀:var $this = $(this)

2) 永远不要在 $ 中包含以 $ 为前缀的 var

3) 始终缓存(保存到 var)任何多次使用的 jQuery 包装的表达式

4) 如果相同的包装对象(如var $items = $('ul li');)在几个类似的函数中出现多次,则将其移至外部作用域并依赖闭包。

【讨论】:

在 .each() 中是否值得这样做 $this = $(this);似乎 $(this) 已经被缓存了?还是我理解错了。 值得缓存; $(this) 不会自动缓存。 谢谢@Pointy。在 .each 中,每个函数调用 this 是下一个集合项;并且 $(anything) 永远不会被好心人缓存【参考方案2】:

如果您正在编写一个将一个 jQuery 对象作为参数的函数,那么您真的应该考虑将其编写为一个 jQuery 插件。

jQuery.fn.yourFunction = function(otherArg1, otherArg2, ...) 
  // ...
;

那就不用写了

yourFunction($(whatever));

你可以写

$(whatever).yourFunction().someOtherJQueryFunction();

在函数内部,this 值将是 jQuery 对象本身。用于最常见的 DOM 相关函数的模式是:

jQuery.fn.yourFunction = function(otherArg1, otherArg2, ...) 
  return this.each(function() 
    var $element = $(this);
    // do stuff ...
  );
;

请注意,在函数的外层,this 没有被包装为$(this),因为它已经被保证是一个 jQuery 对象。在“each()”函数的主体中,或者其他类似的东西中,情况并非如此。

【讨论】:

嗨,Pointy,谢谢,我以后一定会记住这一点。有趣的是,我目前正在开发一个插件,但是在插件中执行 .each 时,您必须使用 $(this) (似乎),这就是为什么我要问是否应该将它作为 jQuery 对象传递。关于在插件内使用 .each() 的任何注意事项以及关于它们的任何提示,还是与在插件外使用它一样? 在插件中使用$(this) 并没有什么坏处,但它是多余的。当您将 jQuery 对象传递给 jQuery 时,它会计算出来并返回给您。【参考方案3】:

如果您打算只将单个元素传递给函数,那么这并不重要。我会根据调用时可能已经掌握的内容来设计函数参数。如果我在调用时从未在 jQuery 对象中使用过它,那么我只需传递一个 DOM 元素并让函数将它变成一个 jQuery 对象(如果需要)。如果我总是已经在一个 jQuery 对象中拥有它,那么传递我已经拥有的那个对象而不是额外的 DOM 元素,然后在函数内将它变成另一个 jQuery 对象会更好。

如果您打算将多个元素传递给函数,那么只传递一个 jQuery 对象可能更容易,因为它是多个对象的一个​​非常方便的包装器。

正如 Pointy 所说,最优雅的解决方案是让你的函数成为一个插件,然后它会自动接受许多不同的参数,包括选择器、DOM 元素、DOM 元素数组或 jQuery 对象(所有这些都由jQuery 基础架构)。

如果你只将 DOM 元素变成一个 jQuery 对象,你将获得最好的性能。传递 DOM 或传递 jQuery 对象作为参数将具有相同的性能(两者都传递对对象的引用)。插件的想法实际上会稍差一些,因为它是通用的并且接受许多不同的参数,因此它必须识别传递的参数类型。与 .index() 方法所花费的时间相比,这种性能差异可能并不明显。

【讨论】:

以上是关于我应该将 jQuery 或 DOM 对象作为参数传递吗? (性能问题)的主要内容,如果未能解决你的问题,请参考以下文章

.Net 将对象列表作为参数传递给 JQuery

将对象的属性作为第二个参数传递给jQuery函数本身

jQuery常用方法

如果生成代码,如何将 DOM 元素和 JSON 对象传递给 JavaScript 函数?

jQuery之核心函数

jQuery中"$"的理解