哪些模式可用于在大型JavaScript应用程序中缓存许多jQuery选择器以便重复使用?
关于在简单函数中的简单变量中存储jQuery选择器有很多说法,但在JavaScript对象中,例如在流行的模块模式中,如何干净地设置和存储它们?
我最初的尝试是使用全局变量,但这会弄脏命名空间并可能导致冲突。我的第二次尝试涉及将选择器存储在相应对象内的对象文字中,但这会导致对它们的调用时间长于所需,例如:
var Module = {
nodes: {},
storeSelectorsInCache: function() {
Module.nodes = {
form: $('#form'),
grid: $('#grid')
};
},
initialize: function() {
Module.storeSelectorsInCache();
// notice the long hierarchy to get to Module.nodes.form
Module.nodes.form.submit(function() {
// event handler
});
}
};
某处必须有一个更清洁的速记。
答案 0 :(得分:4)
这样的事情可能很酷:
var _nodes = {};
var Module = {
/**
* You could call this when you want to query a selector and store it for reuse. Then
* just use this for querying.
*
* @param {String} selector The selector to memoize.
* @param forceUpdate {Boolean} jQuery selectors don't update with their DOM
* counterparts. This will take that into account. Pass in true to override cache.
*
* @return {Object<Array<jQuery>>} The matching selectors.
*/
$: function(selector, forceUpdate) {
if (forceUpdate === true || !({}).hasOwnProperty.call(_nodes, selector)) {
_nodes[selector] = jQuery(selector); // Not that robust, just a basic example
}
return _nodes[selector];
},
initialize: function() {
this.$('#form').submit(function () { /* ... */ });
}
};
因此,每当您使用本地范围的Module.$
函数查询选择器时,它会将结果缓存在节点对象中(此处将被用作关联数组)。但是,如果节点对象中没有该选择器的结果,那么它将查询DOM。此外,还有一个额外的参数可以强制更新nodes
中的选择器。
或者你可以使用lodash的memoize函数,如下所示:
// inside your Module
$: _.memoize(jQuery);