Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If a String is immutable in JavaScript why does the following code mutate a string?

I have read the input as a string and, after splitting it, the string becomes an object.

process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data',(c)=>{
    in += c;
});
process.stdin.on('end',()=>{
    spliter(in);
});
function spliter(in){
    console.log(typeof(in));
    in = in.split('\n');
    console.log(typeof(in));
}
like image 832
Pawan Bishnoi Avatar asked Jun 16 '26 01:06

Pawan Bishnoi


2 Answers

As others have pointed out, in the example provided, the string primitive is not being mutated.

The variable is being re-assigned to the value returned by the split() method, which is being called on a String wrapper object, which is automatically used when calling a method on a string. ​

let myString = 'Hello World!';

console.log("BEFORE reassignment - variable type is: " + typeof(myString));  // string 

myString  = myString.split(' ');  // <----- method called on String object wrapper, returns an array, which is re-assigned to the myString variable   

console.log(myString); //  ['Hello', 'World!']

console.log("AFTER reassignment - variable type is: " + typeof(myString)); // object 

Below is some further context:

The set of types in the JavaScript language consists of primitive values and objects.
Source: MDN Web Docs

A string is a primitive value.

In JavaScript, all primitive types are immutable and have no methods, however: ​

It is important not to confuse a primitive itself with a variable assigned a primitive value. The variable may be reassigned a new value, but the existing value can not be changed in the ways that objects, arrays, and functions can be altered.
Source: MDN Web Docs

Even though primitive types have no methods, it is possible to call a method on a primitive because all primitive values, except for null and undefined, have object equivalents that wrap around the primitive values:

  • String for the string primitive.
  • Number for the number primitive.
  • BigInt for the bigint primitive.
  • Boolean for the boolean primitive.
  • Symbol for the symbol primitive.

Source: MDN Web Docs

When you call a String instance method on a string primitive the following occurs:

  • The primitive value is temporarily converted into an object
  • The object's method property is used
    (e.g slice() will return a new string and split() will return an array of strings)
  • The object is converted back to a primitive

Sources:

  • Head First JavaScript Programming (2014), page 306.
  • JavaScript Programmer's Reference (2010), page 157.
like image 175
user1063287 Avatar answered Jun 18 '26 15:06

user1063287


Your code does not mutate the string.


Strings (along with the other primitive types) are immutable in JS.

Mutating something means that changing it without creating another one.

String modifier methods return a new string, but doesn't change the original, for example:

const a = 'Hello world!'
const b = a.slice(0,5)

console.log(a) //Hello world!
console.log(b) //Hello

However, you can still reassign a string variable with a new string (but that's not mutation):

let a = 'Hello world!'
a = a.slice(0,5)

console.log(a) //Hello

Your code is a bit more complicated. String#split() returns an array of strings, but doesn't mutate the original:

const a = 'Hello world!'
const b = a.split('o')

console.log(a) //Hello world!
console.log(b) //['Hell', ' w', 'rld!']

Arrays are (in fact) objects, and they are mutable, but not the strings (and other primitives) they contain.

like image 21
FZs Avatar answered Jun 18 '26 13:06

FZs



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!