#javascript
#javascript
Вопрос:
Я включал и выключал JavaScript в течение 13 лет, но я как бы заново открыл его в последние несколько месяцев как способ написания программ, которые могут быть использованы любым пользователем, посещающим веб-страницу, без установки чего-либо. См., например.
Проблема, которую я недавно обнаружил, заключается в том, что, поскольку JavaScript свободно типизирован по дизайну, он продолжает объединять строки, когда я хочу, чтобы он добавлял числа. И это непредсказуемо. Одна процедура работала нормально в течение нескольких дней, затем, когда я вводил в нее разные данные, возникла проблема, и я получил невероятно большое число.
Иногда мне удавалось предотвратить это, используя ( )
один термин, иногда мне приходилось прибегать к parseInt()
одному термину или parseFloat()
к одному термину. Это немного напоминает мне попытку принудительно получить результат с плавающей запятой в C, поставив .00 на один (постоянный) член. У меня просто это произошло при попытке =
получить что-то из массива, который я уже загружал, выполняя parseFloat()
все.
Это происходит только в дополнение? Если я использую parseInt()
или parseFloat()
хотя бы на одном из терминов каждый раз, когда добавляю, это предотвратит это? Я использую Firefox 6 под Linux для записи, но переносимость в разных браузерах также вызывает беспокойство.
Ответ №1:
В спецификации говорится об операторе сложения:
Если тип (lprim) является строкой или тип (rprim) является строкой, то
верните строку, которая является результатом объединения toString(lprim), за которым следует toString(rprim)
Это означает, что если хотя бы один оператор является строкой, будет выполняться конкатенация строк.
Если я использую
parseInt()
илиparseFloat()
хотя бы на одном из терминов каждый раз, когда добавляю, это предотвратит это?
Нет, все операнды должны быть числами.
Вы можете легко преобразовать любую числовую строку в число, используя унарный оператор plus (это не изменит значение, если вы уже имеете дело с числом):
var c = a b;
Ответ №2:
Обычно я делаю это:
var x = 2;
var t = "12";
var q = t x; // q == "122"
var w = t*1 x; // *1 forces conversion to number w == 14
Если t не является числом, то вы получите NaN
.
Если вы умножаете переменные на 1, вы не знаете, к какому типу они относятся. Они будут преобразованы в число. Я нахожу этот метод лучше, чем выполнение приведений int и float, потому что *1 работает со всеми типами чисел.
Проблема, с которой вы столкнулись, заключается в том, что функции, которые извлекают значения из DOM, обычно возвращают строки. И даже если это число, оно будет представлено в виде строки при ее извлечении.
Комментарии:
1. Используйте
(t*1||0)
для нескольких дополнений, где недопустимые значения дляt
должны игнорироваться:NaN || 0
= 0 и14 || 0
= 14.
Ответ №3:
Вы можете использовать
operator для преобразования строки в число.
var x = '111'
x === 111
Ответ №4:
Будьте уверены, это очень предсказуемо, вам просто нужно быть знакомым с операторами и типами данных вашего ввода.
Короче говоря, вычисление выполняется слева направо, и конкатенация будет происходить всякий раз при наличии строки, независимо от того, на какой стороне операции.
Так, например:
9 9 // 18
9 '9' // '99'
'9' 9 // '99'
'9' 9 // 18 - unary plus
- '9' 9 // 0 - unary minus
Некоторые троичные выражения:
9 '9' 9 // '999'
9 9 '9' // '189'
Комментарии:
1. Спасибо, я запомню лево-правую вещь. В основном у меня были проблемы с переменными, а не с константами, но похоже, что (1 * A) B тоже может сработать. Мне нравятся удобства обратного проектирования. Страница сохранена на потом. Алан
2. @ab1jx, нет большой разницы между переменными и константами. Они вычисляются идентичным образом, и применяются все те же правила. Упомянутые приемы работают, однако я чувствую, что они не нужны в реальном коде. Должен быть раздел проверки, который отделен от раздела вычислений, для целей обслуживания и ясности (просмотр
1*A B
выглядит странно). Я бы преобразовал все значения в правильные типы и только затем использовал их. В любом случае, удачи!