Я vs JavaScript - 0:1
версия для печатиJavaScript меня иногда в тупик ставит. Причем не баги реализации, а количество свободы в нем. Кстати, багов в js я еще не видел.
Есть у меня некий код. Для примера упростил его максимально. Суть: есть строка, состоящая из цифр. Это - цифровые флаги. Функция разбирает строку на части и согласно полученных цифровых флагов готовит html-код таблицы для вставки на страницу. Каждая шестая и седьмая ячейка нужна другого цвета (практический пример - календарь в меню этого сайта). Еще замечу, что рабочий код этого календаря я сделал много раньше, только попроще. Теперь мне нужно было сделать его слегка круче.
some_code('41000010101011');
function some_code(res) {
var before=res.charAt(0); //Берем первое число
var after=res.charAt(1); //Берем второе число
var code=res.substr(2); //Все, начиная с третьего символа.
...
var cnt=before; //Счетчик "переноса строки"
for (i=1;i<=code.length;i++) {
var cls='';//Определяем доп.классы для ячейки
if ((cnt+2)%7==0 || (cnt+1)%7==0) cls=' holiday';
...
cnt++;//Позднее я переставил инкремент счетчика выше, но тогда не видно, в чем косяк.
if (cnt%7==0) text=text+'<br>';
}
}
В строке 1 вызываем функцию. Это для примера, на деле передаваемый параметр меняется. Косяк в строке 11. По задумке условие должно срабатывать только при значении cnt=5,6,12,13 и .т.д. А получалось, что условие выполнялось, где угодно! Причем условие в строке 14 работает, только когда надо. Я убился искать причину. Обложил все alert-ами, наставил точки останова в Firebug. Смотрел и не видел! %))
Вообщем причина в следующем:
строка 8: переменной cnt присваиваем строковое представление числа. В данном случае - '4'.
строка 11: выражение (cnt+2)%7==0. Сначала конкатенация(!) строк, получаем '42' вместо 6. Потом неявное преобразование типа к числовому и деление по модулю. Получаем 0, а не должно бы, ведь cnt=4, как я думал.. :)
И что совсем сбивало с толку:
Строка 14: условие действительно срабатывает, когда нужно. А все потому, что строкой выше происходит неявное преобразование значения cnt в число и увеличение на единицу.
Вот это был тупик. Я по началу вообще не нашел причин, додумался только переставить инкремент счетчика выше и подправить условие. Что нужно было сделать:
строка 4: var before=Number(res.charAt(0)); //явное преобразование к числу
или хотя бы в строке 8: var cnt=Number(before);
Мораль сей басни такова: я балбес :D Внимательнее нужно книги читать по javascript. Причем, например у Фленагана четко написано "если один из операндов оператора + представляет собой строку (или объект), то другой операнд преобразуется в строку (или оба операнда преобразуются в строки) и операнды конкатенируются, а не складываются." (Девид Флэнаган "JavaScript Подробное руководство" стр. 88).
[1oo%, EoF]Понравилась статья? Расскажите о ней друзьям: