Thanks to both of you for explaining, I thought Java and JavaScript would have similar behavior here and did not know .intern() had to be manually invoked in the former.
Just to clarify where I started from: JS has the notion of String Primitives and String Objects[0], and concatenating two string primitives results in another string primitive. It's as if it always calls .intern(). Except, since from a user perspective there is no option to not intern it, JS implementations are free to do optimizations that don't seem available to Java. Like avoiding heap allocation for provably short-lived strings in the first place, and not interning them if they are never compared (I don't actually know if it does those optimizations, but I imagine it shouldn't be too hard to prove these things with many short functions).
[0] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...