有时我在 Javascript 函数中看到,如果jQuery
重复使用变量到的转换,则可以先将其分配给局部变量:
$variable = $(variable);
这是否必要,转换成本是多少?
有时我在 Javascript 函数中看到,如果jQuery
重复使用变量到的转换,则可以先将其分配给局部变量:
$variable = $(variable);
这是否必要,转换成本是多少?
无论如何,存储对象比每次要在其上使用 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();
这取决于变量是什么。如果原始变量只是单个 DOM 元素,那么它并不是特别昂贵 - DOM 遍历已经完成,所以您要做的就是将该元素包装在 jQuery 伪数组中并附加原型。
但是,如果原始变量是选择器,那么您绝对应该缓存结果以避免重复从 DOM -> 元素列表转换。
无论如何,最好不要重复自己,因此缓存$(variable)
只是良好的代码卫生。
如果$(variable)
无论如何调用,这个赋值基本上没有成本——这只是在内存中存储对对象的引用。
纯粹主义者可能会指出,因为现在存储了 jQuery 对象,所以它不能被垃圾回收,这是真的。所以我想如果你有很多这些可能会导致内存问题,但它本身没有成本可言。
这样做的原因是因为与创建对象相关联的成本,即$(variable)
零件。如果多次这样做可能会很昂贵。存储对对象的引用意味着只需要创建一个。
另一个重要的一点:以下声明
var $variable = $(variable);
如果它是在闭包的调用上下文中完成的,它的行为可能会有所不同。也就是说,如果在 var 语句的范围内定义了一个函数,该变量将“停留”以供该函数使用。这可能具有与上述相同的效果(没有 gc 和指针内存),并增加了更长的生命周期。(因为只要函数有可能被调用,它就会一直存在。)