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
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
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???