I’m writing a little cached function in a plugin / library. It takes a HTMLElement and returns a Decorator.
return function _cache(elem) {
if (elem.id === "") {
elem.id = PLUGIN_NAME + "_" + uid++;
}
if (cache[elem.id] === void 0) {
cache[elem.id] = _factory(elem);
}
return cache[elem.id];
}
Here I’m storing some expensive operation in a cache by the id of the HTMLElement. This is a O(1) lookup but it uses the “bad practice” of setting elem.id and having a side effect.
The alternative would be O(N) lookup on the cache
return function _cache(elem) {
for (var i = 0, ii = cache.length; i++) {
var o = cache[i];
if (o.elem == elem) return o.data;
}
var ret = _factory(elem);
cache.push({ elem: elem, data: ret });
return ret;
}
But this means that my cached expensive method doesn’t have any side effects on the HTMLElement.
Question:
Is this “side effect” innocent and is it worth doing for the optimization on my decorator?
Real Code:
Gist of plugin template where I use this snippet
Edit:
I’m clearly too tired and forgot data-foo exists. Here’s how it should be implemented
var attr = "data-" + PLUGIN_NAME + "-cache";
return function _cache(elem) {
var val = elem.getAttribute(attr);
if (val === null || val === "") {
val = PLUGIN_NAME + "_" + uid++;
elem.setAttribute(attr, val);
}
if (cache[val] === undefined) {
cache[val] = _factory(elem);
}
return cache[val];
}
Instead of using the
id, usedata-x– that’s what it was created for.idhas a specific meaning, is confusing to see it automagically generated (even if properly documented, which is nearly never.) You’re also risking a slight chance of override.