Является ли настройка element.id побочным эффектом плохой практикой? - PullRequest
5 голосов
/ 08 июня 2011

Я пишу небольшую кэшированную функцию в плагине / библиотеке. Он берет HTMLElement и возвращает декоратор.

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];
}

Здесь я храню некоторые дорогостоящие операции в кэше id из HTMLElement. Это O(1) поиск, но он использует "плохую практику" установки elem.id и имеет побочный эффект.

Альтернативой будет O(N) поиск в кэше

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;
}

Но это означает, что мой дорогой кешированный метод не имеет побочных эффектов на HTMLElement.

Вопрос:

Является ли этот "побочный эффект" невинным и стоит ли его оптимизировать на моем декораторе?

Реальный код:

Суть шаблона плагина, где я использую этот фрагмент

Edit:

Я явно слишком устал и забыл data-foo существует. Вот как это должно быть реализовано

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];
}

Ответы [ 2 ]

6 голосов
/ 08 июня 2011

Вместо использования id используйте data-x - это то, для чего оно было создано.

id имеет конкретное значение, сбивает с толку, что оно генерируется автоматически (даже если должным образом задокументировано,что почти никогда.) Вы также рискуете небольшой шанс переопределить.

4 голосов
/ 08 июня 2011

Является ли этот "побочный эффект" невинным

Нет, ясно.Будет ли это хорошо взаимодействовать с другими скриптами на странице?Не знаю ... это зависит от того, для чего он нужен и с какими другими типами сценариев вы ожидаете, что он будет комбинироватьсяВы никогда не сможете создать «плагин», который никогда не выйдет из строя при взаимодействии с другими плагинами и скриптами, но, сводя побочные эффекты к минимуму, вы можете хотя бы попытаться свести его к минимуму.

Обратите внимание, что id не является уникальным идентификатором.Хотя в один конкретный момент времени в документе должен быть только один элемент с заданным идентификатором, (a) можно создать несколько элементов с одинаковым идентификатором и последовательно вставить в документ (возможно, один элемент заменит другой с тем же идентификатором), и(б) люди по-прежнему используют дубликаты, даже если это неправильно.Любой из них приведет к тому, что ваш кэш соберет старые, больше не используемые элементы и вернет их ненадлежащим образом.

К сожалению, не существует функции JavaScript для получения скалярного / хешируемого уникального идентификатора для произвольного объекта;единственный способ получить идентичность объекта - это === - сравнить с другими объектами.

Другим распространенным способом продвижения вперед является добавление к узлу произвольного нового свойства (в терминах IE - «expando») со случайным действительно уникальным идентификатором.Стандарты не гарантируют работоспособность расширений, но они работали во всех браузерах до первого дня и широко используются.

Так, например, jQuery уникально идентифицирует элементы, и если вы пишете плагин дляjQuery, вы можете попробовать воспользоваться этим - jQuery.expando содержит имя произвольного свойства expando, используемого для этой цели ... или, придерживаясь документированного набора функций, data() может быть использовано для добавления ваших собственных метаданных к элементувключая ваш собственный уникальный идентификатор.

У Expandos действительно есть некоторые неприятные побочные эффекты, включая случайную обработку их как атрибутов в IE <9 (которые не могут отличить свойства от атрибута), но если вы 'В любом случае, если вы используете jQuery, вам, вероятно, нечего терять. </p>

стоит ли оптимизировать мой декоратор?

Зависит от того, сколько вы ожидаетеиметь на странице.Сравнение каждого элемента с другим элементом является операцией O ( n ²);терпимый (и, вероятно, предпочтительный, учитывая побочные эффекты), если n низок, но быстро становится неуправляемым по мере роста n .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...