10

I am trying this:

function add_things() {
  var first = '2';
  var second = '4';
  alert(first + second);
}

But it gives me 24 instead of 6, what am I doing wrong?

Tilendor
  • 48,165
  • 17
  • 52
  • 58
  • 5
    There are many ways to add numbers in strings, including alert(+first + +second); To see why... http://stackoverflow.com/questions/1133770/how-do-i-convert-a-string-into-an-integer-in-javascript/1133814#1133814 – Nosredna Aug 03 '09 at 23:54
  • 1
    another more efficient way would be alert(first - -second). – Marius Aug 04 '09 at 07:04

5 Answers5

30

You're concatenating two strings with the + operator. Try either:

function add_things() {
  var first = 2;
  var second = 4;
  alert(first + second);
}

or

function add_things() {
  var first = '2';
  var second = '4';
  alert(parseInt(first, 10) + parseInt(second, 10));
}

or

function add_things() {
  var first = '2';
  var second = '4';
  alert(Number(first) + Number(second));
}

Note: the second is only really appropriate if you're getting strings from say a property or user input. If they're constants you're defining and you want to add them then define them as integers (as in the first example).

Also, as pointed out, octal is evil. parseInt('010') will actually come out as the number 8 (10 in octal is 8), hence specifying the radix of 10 is a good idea.

cletus
  • 616,129
  • 168
  • 910
  • 942
16

Try this:

function add_things() {
  var first = 2;
  var second = 4;
  alert(first + second);
}

Note that I've removed the single quotes; first and second are now integers. In your original, they are strings (text).

Ben M
  • 22,262
  • 3
  • 67
  • 71
  • 4
    Not sure why people are up-voting this so much?! Chances are that the variables are coming from some other source, and can't simply have quotes removed, so one of the conversions in the other answers would be required. – Peter Boughton Aug 04 '09 at 00:03
  • 5
    I think it's a good answer because clearly the asker thought that first and second were numbers. This isn't one of those cases where the coder gets tripped up because they are expecting a number and getting a string instead--Tilendor went to the effort to quote the numbers! – Nosredna Aug 04 '09 at 00:04
  • It answers the question that was asked. – Robert Harvey Aug 04 '09 at 01:03
9

That is one of the "Bad Parts" of JavaScript, as a loosely typed language, the addition and concatenation operator is overloaded.

JavaScript is loosely typed, but that doesn't mean that it has no data types just because a value of a variable, object properties, functions or parameters don't need to have a particular type of value assigned to it.

Basically there are three primitive data types:

  • boolean
  • number
  • string

null and undefined are two special cases, everything else are just variations of the object type.

JavaScript type-converts values of types into a type suitable for the context of their use (type coercion).

In your example were trying to add two objects of type string, so a concatenation occur.

You can "cast" or type convert the variables to number in many ways to avoid this problem:

var a = "2";
var b = "4";
// a and b are strings!
var sum =  Number(a) + Number(b);          // Number constructor.
sum =  +a + +b;                            // Unary plus.
sum =  parseInt(a, 10) + parseInt(b, 10);  // parseInt.
sum =  parseFloat(a) + parseFloat(b);      // parseFloat.

This is I think a very common mistake, for example when reading user input from form elements, the value property of form controls is string, even if the character sequence that it contain represents a number (as in your example).

The "Bad Part" which I talk, is about the dual functionality of the + operator, overloaded to be used for both, numeric addition and string concatenation.

The operation that the + operator will do is determined completely by the context. Only if the both operands are numbers, the + operator perform addition, otherwise it will convert all of its operands to string and do concatenation.

Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • 1
    The "bad" part if any is the looseness of typing in JavaScript. `"2" + 4` would give you 6 as well as `2 + "4"`. But adding *two strings* gives you concatenation. – lc. Aug 03 '09 at 23:55
  • 4
    I think the bad part is the reuse of "+", period. The loose typing is not a bad part. – Nosredna Aug 04 '09 at 00:11
  • @lc, both of your examples result in "24", I think maybe you're talking out your ass. – Breton Aug 04 '09 at 00:51
  • There's some reason that crockford doesn't like the Number() constructor, but I can't for the life of me remember why. – Breton Aug 04 '09 at 00:52
  • I think he doesn't like any of those constructors used with "new". But I don't recall that he complains about them being used to cast. I avoid them. – Nosredna Aug 04 '09 at 01:09
  • Yeah @lc, you only need one operand to be a string for the plus operator to turn into a concat. – Nosredna Aug 04 '09 at 01:11
  • Operator overloading is the issue: In Perl, **`'2' + '4'` = `'2' + 4` = `2 + '4'` = `2 + 4` = `6` and `'2' . '4'` = `'2' . 4` = `2 . '4' = `2 . 4` = 24`**. – Sinan Ünür Aug 04 '09 at 01:18
  • Just use the unary plus operator. It does exactly the same as the Number constructor... – James Aug 04 '09 at 05:25
6

The single quotes cause the values to be treated as characters instead of numbers. '2' + '4' = '24' in the same way that 'snarf' + 'blam' = 'snarfblam'.

snarf
  • 2,684
  • 1
  • 23
  • 26
0

You could also force the interpreter to perform arithmetic when dealing with numbers in string forms by multiplying the string by 1 (since multiplication can't be done on a string, it'll convert to a number if it can):

// fun with Javascript...

alert(first * 1 + second * 1);

But it's probably best to go with CMS's suggestion of using Number() to force the conversion, since someone will probably come along later and optimize the expression by removing the 'apparently unnecessary' multiply-by-one operations.

Community
  • 1
  • 1
Michael Burr
  • 333,147
  • 50
  • 533
  • 760