2

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));
}
user1063287
  • 10,265
  • 25
  • 122
  • 218
Pawan Bishnoi
  • 1,759
  • 8
  • 19
  • 1
    where is any string being mutated? this global variable `in += c;` which you call spliter like `spliter(in)` is unchanged in the code you've posted ... the argument `in`, you change to be an array, but you haven't "mutated a string" – Jaromanda X Dec 15 '19 at 07:07
  • arrays are a type of object in JavaScript. `typeof []` will return `object`. If you want to determine whether it's actually an array, you can use the isArray method it found on the Array constructor: `Array.isArray([])` returns true – Jacob Penney Dec 15 '19 at 07:12
  • Additionally, strings are not immutable in JavaScript. Not sure where you got that misconception. Only const declared variables are immutable. – Jacob Penney Dec 15 '19 at 07:15
  • 3
    @JacobPenney - are you sure? Every single bit of documentation about javascript disagrees with you – Jaromanda X Dec 15 '19 at 07:24
  • @JacobPenney Strings (and all of primitives) are immutable in JS. Their prototypes aren't, but that's another question... – FZs Dec 15 '19 at 07:25
  • I stand corrected. – Jacob Penney Dec 15 '19 at 07:34
  • When you define a variable there are two parts, a reference to a value- and the value itself. Think of it like a pointer. In a constant you can't change what its pointing to but you can still sometimes change stuff about the value. If the value is immutable but you don't define it as a constant than you can just point to a new value. Remember, you can have a `const` and `let` defined var point to the same object and mutate the object – Aidan Jun 04 '23 at 21:36

4 Answers4

2

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.

user1063287
  • 10,265
  • 25
  • 122
  • 218
FZs
  • 16,581
  • 13
  • 41
  • 50
  • @user1063287 I appreciate your efforts to improve this answer, but now it contains a lot of information unrelated to actually answering the question. A detailed answer is good, but an overly detailed answer may make the answer to the question harder to find, especially, when the question isn't a very general one. – FZs Nov 10 '21 at 18:32
  • no worries, have rolled back answer to last edit and added detailed response to another answer. – user1063287 Nov 10 '21 at 22:10
1

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:

user1063287
  • 10,265
  • 25
  • 122
  • 218
0

When you modify a string variable, javascript doesn't actually modify the string that's in memory, it instead creates a brand new string that looks like a modification of the initial string:

    let str = "     hi      ";
    str = str.trim(); // a new string "hi" is created
    console.log(str);

That is all javascript means by saying its strings are immutable. If you want to prevent a string variable from being changed, you can use const:

const str = "Can't change me";
str = "Want to bet?"  // throws error.
Lonnie Best
  • 9,936
  • 10
  • 57
  • 97
0

Quite simply, you are NOT mutating the string

If you were, the following code (based on your code) would output Object in both console.log's

let x = 'this is a string';
function spliter(x){
    x = x.split('\n');
    console.log(typeof(x));
}
spliter(x);
console.log(typeof(x));
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87