Primitive value cannot be altered in js?

I am reading YDKJS series Types and Grammar. And here is one snippet that the author is using:

function foo(x) {
	x = x + 1;
	x; // 3
}

var a = 2;
var b = new Number( a ); // or equivalently `Object(a)`

foo( b );
console.log( b ); // 2, not 3

I have tried change the line

var b = new Number(a);

to

var b = Object(a);

and

var b = a;

But the result remains the same.

Here is the explanation the author gives out :

The problem is that the underlying scalar primitive value is not mutable (same goes for String and Boolean). If a Number object holds the scalar primitive value 2, that exact Number object can never be changed to hold another value; you can only create a whole new Number object with a different value.

When x is used in the expression x + 1, the underlying scalar primitive value 2 is unboxed (extracted) from the Number object automatically, so the line x = x + 1 very subtly changes x from being a shared reference to the Number object, to just holding the scalar primitive value 3 as a result of the addition operation 2 + 1. Therefore, b on the outside still references the original unmodified/immutable Number object holding the value 2.

Can someone explain it in a more direct way (especially the second paragraph)? I don’t understand these 2 paragraph.
If all the primitive values are not changeable, then

var a = 2;
a++;
a;

should give you 2 right?

When you write a++, that is the equivalent to a = a + 1;

So, in this instance you are assigning a completely new value to a.

Even if you had:

function foo(x) {
	x = x + 1;
	x ; // 3
}

var a = 2;
var b = a;
foo(b)
console.log(b);  // 2, not 3

the result would be the same, because inside foo, x is local to foo and does not attempt to change the global variable b. However, if you wrote the following, then you are directly changing the global variable b inside of foo, so b reflects a different value on the outside.

function foo(x) {
	b = x + 1;
	b; // 3
}

var a = 2;
var b = a;
foo(b)
console.log(b);  // 3
1 Like

I see. So this is a local scope vs global scope thing…

I am pretty sure that the author’s explanation is right too, but it just seems a bit too confusing to me.

Also, I think I understand what the author means…. in his book before he gave out the example snippet I posted he said this :

It is true a copy of the reference to this Number object will be passed to the function, but unfortunately, having a reference to the shared object is not going to give you the ability to modify the shared primitive value, like you may expect:

what he means is this: changing the reference of a wrapped primitive value will not affect its real primitive value. (I dont know whether I make this clearer or making it more confusing)
Am I right???

@camperextraordinaire

thanks! :sunny: :smile: