Плагин JQuery Constrain — странная ошибка Javascript

Справочная информация: наше веб-приложение использует подключаемый модуль jquery.constrain.js для обработки ввода данных в некоторых текстовых полях, чтобы разрешить добавление только допустимых символов. Этот плагин допускает различные ограничения данных, используя регулярные выражения, символы белого/черного списка и т. д. До сегодняшнего дня мы использовали версию 1.0 этого плагина без изменений.

Несколько дней назад я заметил, что некоторые текстовые поля по-прежнему позволяют вводить неверные данные. Например, текстовое поле, содержащее только числовые значения, допускало использование буквенных символов и т. д. Оно также отображало ошибку javascript "Объект не поддерживает это свойство или метод". Я отследил его до следующей функции в плагине jquery.constrain.

    function match(item, input, e) {
        var arr = item.chars.split("");
        for (var i in arr) {
            var token = arr[i];
            if (token.charCodeAt(0) == e.which) {
                return true;
            }
        }
        if (item.regex) {
            var re = new RegExp(item.regex);
            if (re.test(String.fromCharCode(e.which))) {
                return true;
            }
        }

        return false;
    };

Отладив этот блок кода, я определил следующее:

  • item — это объект с двумя строковыми свойствами: chars и regex.
  • item.chars — это пустая строка ("") на момент сбоя.
  • arr, результатом item.chars.split(""), как и ожидалось, является пустой массив.

Вот где это странно. Несмотря на то, что arr является пустым массивом, цикл for присваивает допустимое значение i. Значение "удалить". Так что попадаем в петлю. token, очевидно, имеет значение null, поскольку arr["remove"] равно null. Итак, token.charCodeAt(0) выбрасывает.

Я исправил ошибку, добавив оператор if вокруг цикла for следующим образом:

        if (arr.length > 0) {
            for (var i in arr) {
                var token = arr[i];
                if (token.charCodeAt(0) == e.which) {
                    return true;
                }
            }
        }

Тем не менее, я совершенно сбит с толку тем, почему это было необходимо — это ошибка IE, ошибка в плагине или я просто неправильно сдерживаю дыхание, когда компилирую приложение?


person GalacticCowboy    schedule 19.05.2009    source источник


Ответы (1)


Вы никогда не должны использовать for(i in arr) для перебора массивов. Если сценарии добавляют методы к прототипу Array, они также будут повторяться с использованием цикла for(i in arr). Вероятно, это и является причиной ваших ошибок. Вероятно, вы добавили скрипт, модифицирующий цепочку Array.prototype.

Также читайте здесь в разделе «Почему вы должны прекратить использовать for…in для повторения (или никогда не использовать его)»
http://www.prototypejs.org/api/array

person Pim Jager    schedule 19.05.2009
comment
Да, это было так. JQuery модифицирует Array.prototype, а затем мы добавили к нему еще кое-что. Я сообщу автору плагина, а также исправлю нашу локальную версию. - person GalacticCowboy; 19.05.2009