Неправильное добавление двух чисел в JavaScript

Global.alert("base: " + base + ", upfront: " + upfront + ", both: " + (base + upfront));

Приведенный выше код выводит что-то вроде:

base: 15000, upfront: 36, both: 1500036

Почему он соединяет два числа вместо их добавления?

В конечном итоге я хочу установить значение другого поля в эту сумму, используя следующую команду:

mainPanel.feesPanel.initialLoanAmount.setValue(Ext.util.Format.number((base + upfront), '$0,000.00'));

И когда я пытаюсь это сделать, он превращает число в миллионы вместо 15 036,00. Почему?

Ответ 1

Это может случиться, потому что это строки. Попробуйте разобрать их:

Global.alert(
    "base: " + base + ", upfront: " + upfront + ", both: " + 
    (parseInt(base) + parseInt(upfront))
);

Если эти числа являются десятичными, вам понадобится parseFloat.

Ответ 2

Простой пример:

 1 +1 == 2
"1"+1 == "11"
"1"*1 + 1 == 2

Способы превратить строку в число:

  • parseInt(str)
  • parseInt(str,10)
  • parseFloat(str)
  • +str
  • str*1
  • str-0
  • str<<0
  • Number(str)

И вот некоторые из последствий: Results of converting various strings using the above techniques
(источник: phrogz.net)

Number(str) имеет то же поведение, что и str*1, но требует вызова функции.

Я лично использую *1, так как он короток для ввода, но все еще выделяется (в отличие от унарного +), и либо дает мне то, что набрал пользователь, либо полностью проваливается. Я использую parseInt() только тогда, когда знаю, что в конце будет нечисловой контент, который нужно игнорировать, или когда мне нужно проанализировать строку не-base-10.

Вы можете проверить их производительность в своем браузере на странице моего примера.

Ответ 3

Try

Global.alert(
    "base: " + base + ", upfront: " + upfront + ", both: " + 
    (parseInt(base,10) + parseInt(upfront,10))
);

10 указывает базу 10, в противном случае существует вероятность того, что значение, обрабатываемое как восьмеричное, существует.

Ответ 4

Он обрабатывает его как строку. Вы должны выполнить свою математику перед строкой. Пример:

base + upfront + ' string' 

вернет строку "15036".

string + base + upfront

вернет строку 1500036, как вы видите сейчас.

Или используйте parseInt().

Ответ 5

http://jsperf.com/number-vs-parseint-vs-plus/3

Это также может вас заинтересовать. Это просто сравнение производительности методов, уже упомянутых здесь.

Ответ 6

Я не знаю, почему скобки не помогают вам.
Если я попробую

var base = 500;
var upfront = 100;
alert("base: " + base + ", upfront: " + upfront + ", both: " + (base + upfront))

В качестве ответа я получаю 600, так что может быть, что-то происходит в функции Global.alert?

Одной из ошибок дизайна языка является то, что + является оператором сложения и оператором конкатенации. В сочетании с тем, что он свободно набирается и будет действовать неявно, это означает, что он может дать вам некоторые неприятные сюрпризы, если вы не предпримете шаги, чтобы убедиться, что вы действительно добавляете числа, а не конкатенации строк. В этом случае он обрабатывает вашу базу + upfront как строки и, следовательно, конкатенирует.

В любом случае, путь вокруг него может состоять в том, чтобы иметь (base - upfront*-1).