48

Everybody keeps saying that one of JavaScript's problems is using + [example] for string concatenation. Some say the problem is not using +, it's type coercion [see the comments from the previous example]. But strongly-typed languages use + for concatenation and coerce types without any problem. For example, in C#:

int number = 1;
MyObject obj = new MyObject();

var result = "Hello" + number + obj;
// is equivalent to
string result = "hello" + number.ToString() + obj.ToString();

So why is it that string concatenation in JavaScript is such a big problem?

configurator
  • 2,796

4 Answers4

73

Consider this piece of JavaScript code:

var a = 10;
var b = 20;
console.log('result is ' + a + b);

This will log

result is 1020

Which most likely is not what was intended, and can be a hard to track bug.

Mchl
  • 4,113
49

When you say "bad" do you mean "incorrect" or do you mean "slow"? The argument about using mathematical operators to do string concatenation is arguably an "incorrect" argument, but there's also an argument to be made that using + to do a lot of string concatenation can be very slow.

We're not talking about "Hello" + number when we talk about performance, we're talking about building up a relatively large string by repeatedly appending to it in a loop.

var combined = "";
for (var i = 0; i < 1000000; i++) {
    combined = combined + "hello ";
}

In JavaScript (and C# for that matter) strings are immutable. They can never be changed, only replaced with other strings. You're probably aware that combined + "hello " doesn't directly modify the combined variable - the operation creates a new string that is the result of concatenating the two strings together, but you must then assign that new string to the combined variable if you want it to be changed.

So what this loop is doing is creating a million different string objects, and throwing away 999,999 of them. Creating that many strings that are continually growing in size is not fast, and now the garbage collector has a lot of work to do to clean up after this.

C# has the exact same problem, which is solved in that environment by the StringBuilder class. In JavaScript, you'll get much better performance by building up an array of all the strings you want to concatenate, and then joining them together one time at the end, instead of a million times in the loop:

var parts = [];
for (var i = 0; i < 1000000; i++) {
    parts.push("hello");
}
var combined = parts.join(" ");
15

It's not bad to use + for both addition and concatenation, as long as you can only add numbers, and only concatenate strings. However, Javascript will automatically convert between numbers and strings as needed, so you have:

3 * 5 => 15
"3" * "5" => 15
2 + " fish" => "2 fish"
"3" + "5" => "35"  // hmmm...

Perhaps more simply, overloading "+" in the presence of automatic type conversion breaks the expected associativity of the + operator:

("x" + 1) + 3 != "x" + (1 + 3)
kevin cline
  • 33,798
10

The typical issue brought up for string concatenation revolves around a few issues:

  1. the + symbol being overloaded
  2. simple mistakes
  3. programmers being lazy

#1

The first and foremost issue with using + for string concatenation and addition is that you're using + for string concatenation and addition.

if you have variables a and b, and you set c = a + b, there is an ambiguity dependent on the types of a and b. This ambiguity forces you to take extra steps to mitigate the issue:

String Concat:

c = '' + a + b;

Addition:

c = parseFloat(a) + parseFloat(b);

This brings me to my second point

#2

It's very easy to accidentally cast a variable to a string without realizing it. It's also easy to forget that your input is coming in as a string:

a = prompt('Pick a number');
b = prompt('Pick a second number');
alert( a + b );

Will produce unintuitive results because prompt returns the string value of the input.

#3

Needing to type parseFloat or Number() every time I want to do addition is tedious and annoying. I think of myself as smart enough to remember not to mess up my dynamic types, but that doesn't mean I've never messed up my dynamic types. The truth of the matter is that I'm too lazy to type out parseFloat or Number() every time I do addition, because I do a lot of addition.

Solution?

Not all languages use + for string concatenation. PHP uses . to concatenate strings, which helps distinguish between when you want to add numbers and when you want to join strings.

Any symbol could be used to concatenate strings, but most are already used, and it's best to avoid duplication. If I had my way, I'd probably use _ to join strings, and disallow the _ in variable names.

zzzzBov
  • 5,844
  • 1
  • 29
  • 28