2010-09-03 40 views
13
Global.alert("base: " + base + ", upfront: " + upfront + ", both: " + (base + upfront)); 

El código anterior genera algo como:suma de dos números en JavaScript incorrectamente

base: 15000, upfront: 36, both: 1500036 

¿Por qué es que une los dos números en lugar de sumarlos?

que finalmente desea establecer el valor de otro campo de esta cantidad utilizando la siguiente:

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

Y cuando trato de que, Convierte el número en los millones en lugar de 15,036.00. ¿Por qué?

Respuesta

10

Esto puede suceder porque son cadenas. Trate de analizar ellos:

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

Si esos números se decimal que se necesitan el método parseFloat lugar.

+5

-1 debe especificar radix arg para parseInt – goat

1

Lo está manejando como una cadena. Necesitas hacer tus cálculos antes de la cadena. Ejemplo:

base + upfront + ' string' 

devolvería "cadena 15036".

string + base + upfront 

devolvería la cadena 1500036 como está viendo ahora.

O use parseInt().

+0

Está usando paréntesis, por lo que la adición se ejecutará antes de intentar fusionarse con la otra cadena (es decir, no tiene que hacer su matemática "antes" de la cadena si usa paréntesis) . Pero, el análisis funcionaría: el operador ** + ** está tratando al menos uno de sus operandos como cadenas. – palswim

6

Trate

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

El 10 especifica la base 10, de lo contrario la probabilidad de que el valor que se analiza como existe octal.

+0

Solo un comentario menor: mientras tiene razón al especificar siempre que la base es una buena idea, la base predeterminada es de hecho 10 y no octal. Asume octal para cadenas que comienzan desde cero (como '" 0120 "'). –

+0

Así que cambiar de "de lo contrario es octal" a "de lo contrario, la posibilidad de que el valor se analice como octal existe" sería una buena edición? Se trata de las mejores prácticas, ¿verdad? – davidj

+0

+1 para especificar radix – goat

1

No sé por qué los soportes no te están ayudando.
Si intento

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

me pongo 600 como la respuesta, por lo que podría estar allí hay algo que hacer en la función Global.alert?

Uno de los errores del diseño del lenguaje es que + es tanto un operador de adición como un operador de concatenación. Junto con el hecho de que está tipeado libremente y emitirá implícitamente significa que puede darte algunas sorpresas desagradables a menos que tomes medidas para asegurarte de que realmente estás sumando números y no concatenando cadenas. En este caso, trata su base + por adelantado como cadenas y, por lo tanto, concatenando.

De todos modos, la forma de evitarlo podría ser tener (base - upfront*-1) en su lugar.

21

ejemplo simple:

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

formas de convertir una cadena en un número:

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

Y aquí están algunas de las consecuencias: Results of converting various strings using the above techniques http://phrogz.net/JS/string_to_number.png

Number(str) tiene el mismo comportamiento que str*1, pero requiere una llamada de función.

Yo personalmente uso *1, ya que es corto de escribir, pero aún se destaca (a diferencia del unario +), y ya sea me da lo que el usuario escribió o falla por completo. Solo uso parseInt() cuando conozco que habrá contenido no numérico al final para ignorar, o cuando necesito analizar una cadena que no sea de base-10.

Puede probar el rendimiento de estos en su navegador at my example page.

+0

+1, '+ s' y' s * 1' no son solo palabras cortas, sino más correctas. –

+0

+1 para aclarar la cadena al número – kjy112

+0

+1. Añadiré que 'Number()' también puede darte resultados extraños. Por ejemplo, '+" "' y '+" "' dará como resultado '0' donde' parseInt ("", 10) 'devolverá' NaN'. 'Number()' recorta el espacio en blanco antes de la conversión y una cadena vacía después del recorte siempre dará como resultado '0'. Al igual que los altibajos con otros métodos, si este comportamiento es deseado o no puede variar según el uso. Muy a menudo, uso '+' (se destaca lo suficiente para mí), pero definitivamente vale la pena asegurarse de no quedar atrapado por lo que podrían parecer fantasmas en la máquina. –

Cuestiones relacionadas