Variables are not typed; their values are. The conversion between a
string and a number happens automatically. Since plus (` + `) is
also used as in string concatenation, ` '1' + 1 ` is equal to ` '11' `.
The string determines what ` + ` does. To overcome this, first convert the
string to a number. For example: ` +varname ` or ` Number(varname) ` or
` parseInt(varname, 10) ` or ` parseFloat(varname) `.
Form control values are strings, as is the result from a ` prompt `
dialog. Convert these to numbers before performing addition by using
the unary ` + ` operator: ` +'1' + 1 ` result is ` 2 `.
Additional Notes:
http://www.jibbering.com/faq/faq_notes/type_convert.html
http://msdn2.microsoft.com/en-us/library/67defydd.aspx
The complete comp.lang.javascript FAQ is at
http://jibbering.com/faq/index.html.
--
The sendings of these daily posts are proficiently hosted
by http://www.pair.com.
Multiply variables by 1 in order to tell javascript that you want a
number answer
var answer=1*str+24;
Surprisingly, that method appears to be the fastest in JavaScript 1.8,
indeed. I get (pretty-printed)
min (ms) avg (ms) max (ms)
---------------------------------------------
Number(x) 32 33.4 37
parseFloat(x) 14 15.2 16
parseInt(x, 10) 11 12.6 15
+x 11 11.4 12
1*x 6 6.3 7
---------------------------------------------
using the following benchmark in Firebug 1.4X.0a31 in Mozilla/5.0 (X11; U;
Linux i686; en-US; rv:1.9.0.9) Gecko/2009050519 Iceweasel/3.0.9
(Debian-3.0.9-1):
if (Math.min(3, 2, 1) != 1)
{
/* JavaScript 1.8 doesn't go here */
Math.min = function() {
var result = arguments[0];
for (var i = 1, len = arguments.length; i < len; i++)
{
var a = arguments[i];
if (result < a) result = a;
}
return result;
};
}
if (Math.max(1, 2, 3) != 3)
{
/* JavaScript 1.8 doesn't go here */
Math.max = function() {
var result = arguments[0];
for (var i = 1, len = arguments.length; i < len; i++)
{
var a = arguments[i];
if (result > a) result = a;
}
return result;
};
}
Math.avg = function() {
var sum = 0, len = arguments.length;
for (var i = len; i--;) sum += parseFloat(arguments[i]);
return sum / len;
};
function benchmark(f, s)
{
var runs = [];
for (var j = 10; j--;)
{
var d = new Date();
for (var i = 10000; i--;)
{
f();
}
runs.push(new Date() - d);
}
console.log(s || String(f), ": min=", Math.min.apply(null, runs), "ms,
avg=", Math.avg.apply(null, runs), "ms, max=", Math.max.apply(null, runs),
"ms");
}
benchmark(function() { Number("12345") + 12345; }, "Number(x)");
benchmark(function() { parseFloat("12345") + 12345; }, "parseFloat(x)");
benchmark(function() { parseInt("12345"), 10 + 12345; }, "parseInt(x, 10)");
benchmark(function() { +"12345" + 12345; }, "+x");
benchmark(function() { 1*"12345" + 12345; }, "1*x");
It should be noted, though, that while parseFloat() and parseInt() are not
the fastest solutions there, they are arguably the safest.
PointedEars
Ouch! Must be
if (Math.min(3, 2, 1) != 1)
{
/* JavaScript 1.8 doesn't go here */
Math.min = function() {
var result = arguments[0];
for (var i = 1, len = arguments.length; i < len; i++)
{
var a = arguments[i];
if (a < result) result = a;
}
return result;
};
}
if (Math.max(1, 2, 3) != 3)
{
/* JavaScript 1.8 doesn't go here */
Math.max = function() {
var result = arguments[0];
for (var i = 1, len = arguments.length; i < len; i++)
{
var a = arguments[i];
if (a > result) result = a;
}
return result;
};
}
Fortunately, JavaScript 1.8 uses its native implementations instead, so the
benchmark results there are OK.
PointedEars
Interesting, indeed.
[...]
I ran your test on Safari (2.x, 3.x, 4.x) and Opera (9.x, 10.x) on Mac
OS X (10.5.7) to see how they compare (number of iterations was changed
from 10,000 to 100,000, to get a more significant difference).
In Opera, the difference between `+` and `*` is hardly noticeable. `*`
actually comes out to be a tiny bit slower.
Opera 9.25:
Number(x): min=192ms, avg=196.9ms, max=220ms
parseFloat(x): min=216ms, avg=216.7ms, max=218ms
parseInt(x, 10): min=191ms, avg=193ms, max=194ms
+x: min=91ms, avg=91.8ms, max=94ms
1*x: min=92ms, avg=92.8ms, max=95ms
Opera 9.64:
Number(x): min=71ms, avg=77.2ms, max=99ms
parseFloat(x): min=62ms, avg=62.8ms, max=65ms
parseInt(x, 10): min=76ms, avg=77.1ms, max=78ms
+x: min=40ms, avg=40.3ms, max=41ms
1*x: min=41ms, avg=41.9ms, max=45ms
Opera 10b:
Number(x): min=71ms, avg=75ms, max=89ms
parseFloat(x): min=62ms, avg=63.8ms, max=66ms
parseInt(x, 10): min=80ms, avg=80.9ms, max=82ms
+x: min=40ms, avg=40.5ms, max=41ms
1*x: min=43ms, avg=44ms, max=45ms
Then there's a pretty much similar picture with Safari:
Safari 2.0.4:
Number(x): min=408ms, avg=409.1ms, max=414ms
parseFloat(x): min=469ms, avg=470.6ms, max=478ms
parseInt(x, 10): min=532ms, avg=534.4ms, max=536ms
+x: min=270ms, avg=271.4ms, max=272ms
1*x: min=308ms, avg=308.9ms, max=310ms
Safari 3.0.4:
Number(x): min=71ms, avg=71.5ms, max=73ms
parseFloat(x): min=74ms, avg=74.7ms, max=75ms
parseInt(x, 10): min=78ms, avg=78.1ms, max=79ms
+x: min=61ms, avg=61.7ms, max=62ms
1*x: min=62ms, avg=62.8ms, max=63ms
Safari 4:
Number(x): min=14ms, avg=14.6ms, max=15ms
parseFloat(x): min=14ms, avg=14ms, max=14ms
parseInt(x, 10): min=11ms, avg=11.8ms, max=12ms
+x: min=8ms, avg=8.2ms, max=9ms
1*x: min=8ms, avg=8ms, max=8ms
I also checked FF3.5beta4 and it did have quite large difference similar
to FF3.0.x:
Firefox 3.5beta4:
Number(x): min=161ms, avg=162.6ms, max=164ms
parseFloat(x): min=81ms, avg=81.3ms, max=82ms
parseInt(x, 10): min=67ms, avg=67.3ms, max=68ms
+x: min=0ms, avg=40.3ms, max=81ms
1*x: min=0ms, avg=6.1ms, max=57ms
It is indeed quite amazing that ratio of Number <==> * is ~1.8 in Safari
4 and ~26.6 in FF3.5beta4
--
kangax
~52x in my tests:
http://jorgechamorro.com/cljs/061/
Number(x) 3662453.33Hz (0.00027304ms)
parseFloat(x) 4612737.15Hz (0.00021679ms)
parseInt(x) 8127370.74Hz (0.00012304ms)
+x 4587936.82Hz (0.00021796ms)
1*x 191616542.36Hz (0.00000522ms)
--
Jorge.