10

有时我在 Javascript 函数中看到,如果jQuery重复使用变量到的转换,则可以先将其分配给局部变量:

$variable = $(variable);

这是否必要,转换成本是多少?

4

3 回答 3

6

无论如何,存储对象比每次要在其上使用 jQuery 方法时都必须重新实例化 jQuery 对象要快……即使它对于缓存$(this)$(anObject).

用于描述这种“现在存储,以后使用”方法的术语是“缓存”。它通常被称为“缓存”的原因是因为缓存是指存储一次对某事物的引用并使用它,而无需稍后再返回以再次获取相同的事物(非常非技术性,非 100% 准确的描述)。

重点是处理选择器。jQuery 每次都必须查询 DOM,这是昂贵的部分。与 DOM 操作(以及 jQuery 首先处理您的选择)相比,生成对象和存储引用并没有那么昂贵。

如果您只是从对象引用中创建一个 jQuery 对象,那么它几乎没有破坏性,因为发生的处理是创建 jQuery 对象......所以它实际上仅限于 jQuery 所做的任何事情。这仍然是一种很好的做法,并且仍然可以防止一些不必要的处理。例如,这个:

var element = document.getElementById("div_id");
$(element).someMethod();
// Later:
$(element).someOtherMethod();

效率稍低,因为每次都会创建一个新的 jQuery 对象。它可以很容易地被压缩为在一个变量中存储对单个 jQuery 对象的引用,并引用它。

我能想到的一个警告是它不是一个实时的元素列表(如果选择 DOM 元素)。例如,您可能希望使用 class 缓存所有元素testing-class,如下所示:

var myelements = $(".testing-class");

但是如果将另一个元素添加到带有testing-class类的 DOM 中,myelements则不会被反映。它将具有相同的先前列表。所以在这种情况下,显然需要重新查询和更新 DOM myelements

对我来说,缓存的最佳实践是在一个范围内......而不是整个页面。如果您正在运行一个函数,并且它选择了一些元素,请在开头缓存它,然后使用它。但是不要全局缓存它并在整个页面中使用它;将其缓存一个执行周期。

例如,我会这样做:

function someFunc() {
    var elements = $(".class-stuff");
    // Use `elements` here

    // code

    // Use `elements` here
    someOtherFunc(elements);
}

function someOtherFunc(el) {
    // Use `el` here
}

someFunc();

// Some time later:
someFunc();

但我不会这样做:

var elements = $(".class-stuff");

function someFunc() {
    // Use `elements`
}

function someOtherFunc() {
    // Use `elements`
}

someFunc();
someOtherFunc();

// Some time later
someOtherFunc();
于 2013-04-25T18:45:44.257 回答
1

这取决于变量是什么。如果原始变量只是单个 DOM 元素,那么它并不是特别昂贵 - DOM 遍历已经完成,所以您要做的就是将该元素包装在 jQuery 伪数组中并附加原型。

但是,如果原始变量是选择器,那么您绝对应该缓存结果以避免重复从 DOM -> 元素列表转换。

无论如何,最好不要重复自己,因此缓存$(variable)只是良好的代码卫生。

于 2013-04-25T18:48:41.753 回答
0

如果$(variable)无论如何调用,这个赋值基本上没有成本——这只是在内存中存储对对象的引用。

纯粹主义者可能会指出,因为现在存储了 jQuery 对象,所以它不能被垃圾回收,这是真的。所以我想如果你有很多这些可能会导致内存问题,但它本身没有成本可言。

这样做的原因是因为与创建对象相关联的成本,即$(variable)零件。如果多次这样做可能会很昂贵。存储对对象的引用意味着只需要创建一个。

另一个重要的一点:以下声明

var $variable = $(variable);

如果它是在闭包的调用上下文中完成的,它的行为可能会有所不同。也就是说,如果在 var 语句的范围内定义了一个函数,该变量将“停留”以供该函数使用。这可能具有与上述相同的效果(没有 gc 和指针内存),并增加了更长的生命周期。(因为只要函数有可能被调用,它就会一直存在。)

于 2013-04-25T18:46:34.130 回答