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?

3
  • 1
    Possible duplicate of Understanding Javascript immutable variable Commented Oct 10, 2015 at 12:40
  • I actually read through that post, but could not find the answer Commented Oct 10, 2015 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). Commented Oct 10, 2015 at 14:59

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

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
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.
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.
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}
}

2 Comments

var a = new String('abc'); a is a object,not primitive. so why it is still not changeable
because the underlying data it works on is immutable. It is a language design decision. A feature not a bug, if you will.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.