Are JavaScript strings immutable? Do I need a string builder in JavaScript?
They are immutable. You cannot change a character within a string with something like var myString = "abbdef"; myString[2] = 'c'
. The string manipulation methods such as trim
, slice
return new strings.
In the same way, if you have two references to the same string, modifying one doesn't affect the other
let a = b = "hello";
a = a + " world";
// b is not affected
However, I've always heard what Ash mentioned in his answer (that using Array.join is faster for concatenation) so I wanted to test out the different methods of concatenating strings and abstracting the fastest way into a StringBuilder. I wrote some tests to see if this is true (it isn't!).
This was what I believed would be the fastest way, though I kept thinking that adding a method call may make it slower...
function StringBuilder() {
this._array = [];
this._index = 0;
}
StringBuilder.prototype.append = function (str) {
this._array[this._index] = str;
this._index++;
}
StringBuilder.prototype.toString = function () {
return this._array.join('');
}
Here are performance speed tests. All three of them create a gigantic string made up of concatenating "Hello diggity dog"
one hundred thousand times into an empty string.
I've created three types of tests
- Using
Array.push
andArray.join
- Using Array indexing to avoid
Array.push
, then usingArray.join
- Straight string concatenation
Then I created the same three tests by abstracting them into StringBuilderConcat
, StringBuilderArrayPush
and StringBuilderArrayIndex
http://jsperf.com/string-concat-without-sringbuilder/5 Please go there and run tests so we can get a nice sample. Note that I fixed a small bug, so the data for the tests got wiped, I will update the table once there's enough performance data. Go to http://jsperf.com/string-concat-without-sringbuilder/5 for the old data table.
Here are some numbers (Latest update in Ma5rch 2018), if you don't want to follow the link. The number on each test is in 1000 operations/second (higher is better)
Browser | Index | Push | Concat | SBIndex | SBPush | SBConcat |
---|---|---|---|---|---|---|
Chrome 71.0.3578 | 988 | 1006 | 2902 | 963 | 1008 | 2902 |
Firefox 65 | 1979 | 1902 | 2197 | 1917 | 1873 | 1953 |
Edge | 593 | 373 | 952 | 361 | 415 | 444 |
Exploder 11 | 655 | 532 | 761 | 537 | 567 | 387 |
Opera 58.0.3135 | 1135 | 1200 | 4357 | 1137 | 1188 | 4294 |
How to make mutation of a string? JavaScript
You are trying to change a primitive String
, which is immutable in Javascript.
For exmaple, something like below:
var myObject = new String('my value');
var myPrimitive = 'my value';
function myFunc(x) {
x.mutation = 'my other value';
}
myFunc(myObject);
myFunc(myPrimitive);
console.log('myObject.mutation:', myObject.mutation);
console.log('myPrimitive.mutation:', myPrimitive.mutation);
Should output:
myObject.mutation: my other value
myPrimitive.mutation: undefined
But you can define a function in primitive String's prototype, like:
String.prototype.replaceAt=function(index, replacement) {
return this.substr(0, index) + replacement+ this.substr(index + replacement.length);
}
var hello="Hello World"
hello = hello.replaceAt(2, "!!")) //should display He!!o World
Or you can just assign another value to s.a, as s.a = 'Hello World'
If strings are immutable in Javascript, why does the += operator work the way it does?
I think it's because of the short hand addition operator (+=)
you're using.
It's actually doing 2 operations first addition
then assignment
.
let x = 2;
x += 2;
// The above line is equivalent to the following.
x = x + 2;
So for you're example
let str = "hello";
str += "world"; // is the same as
str = str + "world";
So we are making a new string by str + "world"
then assigning it to our str
variable. So it's still immutable :)
Why the first code works and the second does not work?
item.toUpperCase();
returns the uppercased string that is why when you do item = item.toUpperCase();
the uppercased string is assigned to item
and since item
is a array element, the element is changed by its reference.
Javascript string object readonly?
Strings are immutable, so yes. a
should be reassigned if you want to change the string. You can also use slice
: a = 'j'+a.slice(1)
, or a replace
: a = a.replace(/^h/i,'j')
.
You could create a custom mutable String
object, something like this experiment (esp. see method replaceCharAt
).
Related Topics
How to Check For a #Hash in a Url Using JavaScript
Jquery Scroll() Detect When User Stops Scrolling
Convert String to Variable Name in JavaScript
How to Show a Running Progress Bar While Page Is Loading
How to Import Variables from JavaScript to SASS or Vice Versa
Bootstrap Modal: Background Jumps to Top on Toggle
Iphone/iPad Triggering Unexpected Resize Events
How to Have a Host and Container Read/Write the Same Files with Docker
Change the Selected Value of a Drop-Down List with Jquery
Check If an Array Contains Any Element of Another Array in JavaScript
I Keep Getting "Uncaught Syntaxerror: Unexpected Token O"
I'Ve Heard Global Variables Are Bad, What Alternative Solution Should I Use
CSS Hover VS. JavaScript Mouseover
Get the Scale Value of an Element
How to Animate a Progressive Drawing of Svg Path
Change Text on Hover, Then Return to the Previous Text
How to Build & Deploy a Samsung Smarttv App Without the Ide (E.G: on Linux)