0
Fixed

jQuery плагин - ошибка при обходе массива через for key in и расширенными прототипами Array

Кирилл Егоренков 1 year ago in Подсказки • updated by Антон 8 months ago 4

Доброго времени суток.


В проекте используем jQuery плагин (suggestions-jquery) стабильной версии 17.10.1

При расширении прототипа объекта Array (методы для удаления элемента из массива по значению и др.), в поиске появляется ошибка на подсказках по адресам, связанная с тем, что данный метод (св-во) объекта Array перечисляется при обходе массива через цикл for(historyValueIndex in historyValues) в методе getFormattedHistoryValues. И для функций расширений пытается вызваться toLowerCase().

Так же подобный перебор происходит в методе findUnusedTokens.



Обход массива через данный цикл - плохой тон. Как правило, предлагается проверять наличие св-ва в массиве через .hasOwnProperty, но не хотелось бы лезть руками в плагин, ведь для него выходят более свежие версии.


Прилагаю код методов.


/**
     * Возвращает исторические названия для слов запроса, для которых не найдено совпадения в основном значении
     */
    getFormattedHistoryValues: function(unusedTokens, historyValues) {
        var tokenIndex,
            token,
            historyValueIndex,
            historyValue,
            values = [],
            formatted = '';

        for(historyValueIndex in historyValues) {
            historyValue = historyValues[historyValueIndex];
            for(tokenIndex in unusedTokens) {
                token = unusedTokens[tokenIndex];
                if (historyValue.toLowerCase().indexOf(token) >= 0) {
                    values.push(historyValue);
                    break;
                }
            }
        }

        if (values.length > 0) {
            formatted = ' (бывш. ' + values.join(', ') + ')';
        }

        return formatted;
    },



Метод findUnusedTokens из плагина 


/**
     * Возвращает список слов в запросе для которых не найдено соответствующего слова в ответе
     */
    findUnusedTokens: function(tokens, value) {
        var tokenIndex,
            token,
            unused = [];

        for(tokenIndex in tokens) {
            token = tokens[tokenIndex];
            if (value.indexOf(token) === -1) {
                unused.push(token);
            }
        }

        return unused;
    },


Спасибо.




Answer

Answer
Fixed

Исправлено в 18.3.3

Under review

Кирилл, добрый день! А почему обход массива через for (idx in arr) — плохой тон? Дайте пруф, пожалуйста.

Здравствуйте.


Как такового пруфа предоставить не смогу, по большей части это негласное соглашение. "Best practices" - использовать в данном случае для обхода массива обычный цикл for.., либо тот же for (idx in arr), но в купе например с проверкой .hasOwnProperty, т.к. нужно проверять на унаследованные свойства.


Из MDN: (https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/for...in

"Если вы хотите рассматривать только свойства самого объекта, а не его прототипов, используйте getOwnPropertyNames()hasOwnProperty() или propertyIsEnumerable. Кроме того, если вы знаете, что не будет вмешательства в код извне, вы можете расширить встроенные прототипы методом проверки."

Спасибо.

Planned

Окей, мы изменим способ обхода при случае. Если хотите, присылайте пулл-реквест — будем признательны.

Answer
Fixed

Исправлено в 18.3.3