0

Primitives are immutable, there is no way to change its value.

var a = 'abc';
a[0] = 'b';
console.log(a);// abc as it is immutable

However, if I use wrapper object

var a = new String('abc');
typeof a// object
a[0] = 'b';
console.log(a);//  abc      <----- I actually expect it to be bbc as a is a object which by default should be mutable.

Can someone explain this to me? Is it my misunderstanding of the concept of "mutable" and "immutable" that makes myself confused?

Xuzheng Wang
  • 531
  • 5
  • 17
  • 1
    Possible duplicate of [Understanding Javascript immutable variable](http://stackoverflow.com/questions/16115512/understanding-javascript-immutable-variable) – Simone Nigro Oct 10 '15 at 12:40
  • I actually read through that post, but could not find the answer – Xuzheng Wang Oct 10 '15 at 12:43
  • There is no "wrapper" object, `new String()` creates a String object. You can't reference or modify the internal string value, you can only read it (e.g. using *valueOf*). This allows primitives to be treated like objects for convenience when calling methods, but it doesn't allow for assigning values (which, if possible, would make life extremely confusing). – RobG Oct 10 '15 at 14:59

2 Answers2

2

The object wrapper as the name indicates is a wrapper. primitives do not have properties or methods, this is where the wrapper comes into play and allows you to have methods and properties.

that's why

var a = 'abc';
a.slice(1)// <-- this only works because of a wrapper.

so basically the wrapper object for string is just wrapping the immutable primitive.

in a very abstract manner

var str = new String("a");

is like

var str = {
   primitiveValue:"a",
   slice: function(myStr){//do something}
}
Saar
  • 2,276
  • 1
  • 16
  • 14
2

In the second example, the String object is still backed by a primitive string value. "Wrapping" the value in an object doesn't change the underlying primitive's immutability.

See output from the console:

String {0: "a", 1: "b", 2: "c", length: 3, [[PrimitiveValue]]: "abc"}
0: "a"
1: "b"
2: "c"
length: 3
__proto__: String
[[PrimitiveValue]]: "abc"

The String object simply has an extended prototype to provide functionality. It doesn't change the behavior of the underlying primitive.

defines
  • 10,229
  • 4
  • 40
  • 56
  • So there is a difference between wrapper objects and other objects. I try the following `var a = {0:"a"}; a[0] = 2; a //Object{0:2}` here, the object is changed – Xuzheng Wang Oct 10 '15 at 12:51
  • No, there's actually no such thing as "wrapper objects". In your example, you've created an object with a value at member 0 and then reassigned the reference of that member 0. You never actually change the value of the string you originally set, you just change which string is addressed by that member of the object. The String prototype simply provides functions that can act against a primitive. The primitive cannot be changed, but the variable can be reassigned. You can always set (assign) a variable to anything, but whether or not the value itself is mutable is another question. – defines Oct 10 '15 at 13:02
  • To wit, you could always implement your own string prototype or functions that appear to act like the underlying value is mutable. But the primitive will never be mutable. Such a prototype would simply assign a new value to the underlying variable, not actually change an immutable primitive. – defines Oct 10 '15 at 13:06