2

As I know there are 4 primitives in JS (those that store value directly, rather than reference to another memory location) - String, Number, Boolean, Symbol. I am not counting undefined, null - as they are special data-types, and don't share Object-Constructor via inheritance-chain.)

Now, another property of primitives is that they are Immutable or unchanging. Their values cannot be changed. I conclude that means, for the same variable - the values should not change (ever).

Now, kindly explain to me, in the following cases - how these data-types remain unchanged?

var str = "Good Morning";
var bool = true;
var num = 29;

str = str.replace("M", "Z");
bool = !bool;
num+=5;

console.log(str, bool, num);

For same variable, I have changed all - string, bool, number. Then how these variables (of respective primitive data-types) are Immutable in JS?

Deadpool
  • 7,811
  • 9
  • 44
  • 88

3 Answers3

2

You are not mutating the existing primitives. You're simply assigning new primitive values (which are immutable as well) to the existing variable names.

Mutation is not the same thing as variable name reassignment. Mutation looks something like the following:

someObj.someProp = newPropVal;

Reassignment is:

someVarName = newVal;

Primitives don't have own-properties; trying to assign to a property of a primitive doesn't do anything and will throw an error in strict mode, because primitives are immutable.

Here's one way of looking at it (it's a nice visualization, though it's necessarily an accurate reflection of what's actually happening in the bytecode): values reference a location in memory. Variable names point to locations in memory. Say that false corresponds to memory location 1234, and you create an object {} which corresponds to memory location 9999. You can assign false to a variable name and have that variable name point to location 1234 in memory. You can reassign the value that the variable name points to by using location 9999 instead, that points to the object. The object, unlike the primitive, is a potential container for other values (and other memory locations). The primitive cannot act as such a container.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • you mean `variable value reassignment` .. .a variable name is immutable :p – Jaromanda X Sep 07 '20 at 06:44
  • @CertainPerformance - Nice to see you long time. Can you please elaborate a little, I am very confused for this topic. – Deadpool Sep 07 '20 at 06:44
  • @CertainPerformance - but then how can we see the mutation in strings or numbers, because. The variables store the 'value' directly, (not the reference to another memory location). You mean, that as soon as we make change (or some new calculation is done), the old value will be discarded or trashed, and new value will be put at the memory-location? Something like that? – Deadpool Sep 07 '20 at 06:49
  • 2
    @Deadpool The variable names don't store the value directly exactly, but you can look at them like they store a *memory location*, and that memory location may hold a primitive or an object. If you assign a new value to the variable, you're changing the location in memory that the name points to. Mutation, in contrast, keeps the same link between a variable name and its object value, but changes one of the object's properties. – CertainPerformance Sep 07 '20 at 06:55
  • @CertainPerformance - Just to conclude. This means `primtive` and `object/array/date/promse` both types variables -- just contain address of another memory location? So, as we learnt -- `primitives` contain data-directly, and `non-primitives (objects, arrays, dates, etc.)` -- contain `reference/memory-location` of where there data stored is `technically-wrong`. As, at-first-level --- all data-type-variables, **I mean all** --- only contain just another address. Its just that -- that 2nd address --will contain `a data (string, number)` or `an Object (another set of memory addresses for props)`? – Deadpool Sep 07 '20 at 07:05
  • 2
    @Deadpool Objects can contain addresses to other memory locations (as properties of the object); primitives can't, since they don't have properties. The primitive will be just that, the primitive, all you can do with it is change the variable reference to somewhere else. But with objects, you can change what their nested addresses point to. This is just one way of looking at it, which suffices for anyone who's only looking for a relatively easy way to understand the behavior. (I find this approach quite intuitive, but YMMV.) I won't pretend to know what the compiled bytecode *actually* does. – CertainPerformance Sep 07 '20 at 07:15
1

Values are immutable; variables are not; they hold a reference to their (primitive) values.

So:

Objects are mutable by default

Objects have unique identities and are compared by reference

Variables hold references to objects

Primitives are immutable

Primitives are compared by value, they don’t have individual identities

This is from: Understanding Javascript immutable variable

Oliver Su
  • 84
  • 10
1

your means to change primitives are only reassigning the variable's reference to the stack

var a = 1;
a = 2;

here a is a reference address to the execute stack. Above reassignment only changes the address in stack, not 1 itself. If 1 is stored in address ****, after the reassignment, 1 is still located at ****, but a now points to 2's address in stack

fengxh
  • 384
  • 2
  • 8