I’m learning about string concatenation in JavaScript and how it compares to Java.
In Java, if you write:
final String LET = "a";
final String OOO = "aaaaa";
final String LET_OOO = LET + OOO;
The compiler combines these constant strings at compile time, so NO new string is created at runtime.
Can JavaScript do the same? For example:
const a = "a";
const b = "bbb";
const c = a + b;
I expected that since both are constants, JavaScript might optimize and not create a new string in memory—similar to how Java combines final strings at compile time.
Does JavaScript (like V8) concatenate these without creating a new string in memory? Or does it always create a new string?
(V8 developer here.)
Short answer: yes, V8 can optimize this.
Long answer: it depends. JavaScript as a language makes no promises one way or the other; this is an example of an "invisible" optimization that engines are free to implement or not. V8 supports constant folding for strings in its parser and in its optimizing compiler. Unsurprisingly, its interpreter and baseline compiler don't perform optimizations, including constant folding.
Let's illustrate: consider the functions
function f1() { console.log("a" + "b"); }
function f2() { console.log("ab"); }
function f3() {
let a = "a"; // "let" or "const" or "var" makes no difference in this case.
let b = "b";
console.log(a + b);
}
Functions f1
and f2
will generate the same bytecode, because the parser constant-folds "a" + "b"
. Since the parser has limited context, it can only do that for string literals immediately following each other; it cannot inspect variables etc.
Function f3
will perform an actual string concatenation every time it runs in an unoptimized tier. Once it gets optimized, it'll generate the same optimized code as f1
and f2
, because the optimizing compiler does have the smarts (and is allowed to take the time) to analyze what's happening in the function and perform applicable optimizations.