Setting a variable equal to another variable

In your first case:

var a = {
  fname: "Jon",
  lname: "Smith",
  age: 50
}

var b = a;
a = {}

b remains unchanged because this is the sequence of events happening in the background:

  • You create an object at memory address 0x1234 with the data

    fname: "Jon", lname: "Smith", age: 50

  • A pointer to that memory block is stored ina.

  • Then that pointer is copied to b

At this point there are two references to the same bit of memory. Altering anything in that memory block will affect both the references to it.

  • a = {} doesn't clear out memory block 0x1234, but creates a new object on another memory location (0x1235) and stores a pointer to that block in a. The memory at 0x1234 remains unchanged because b is still pointing to it.

There is a difference in this sort of memory management between simple variables and objects/pointers. Strings and numbers are of the simple variety and are 'passed by value' as opposed to being 'passed by reference' for objects.


Let me try to explain:

1) In your example a and b are references to one and the same object, while a.fname (or b.fname) is an attribute of that object. So when manipulating the attribute it will be changed in the object, while the references won't be affected, they still point to the same object, the object itself has been changed. a = {} on the other hand will just replace the reference to the object without affecting the object itself or b's reference to It.
It's no clearance btw you only just created a new reference to a new empty object.

2) These are not objects, so there is no reference you are directly manipulating the values. That' s because there's a difference between objects and primitives which might get confusing especially in the beginning if you're not used to working with strict types.


The really short answer to both your questions is that when you make one variable equal to another, a COPY of what's in the first variable is made and stored in the second variable - there is no linkage between the two variables.

But, read on for more details and why it can seem like there is a link in some cases...


JavaScript, like many languages, divides data into two broad categories: value types and reference types. JavaScript value types are its primitives:

  • string
  • number
  • boolean
  • null
  • undefined
  • symbol

When you assign any of these types to a variable, the actual data is stored in that variable and if you set one variable equal to another, a copy (not a linkage) of the primitive is made and stored in the new variable:

var a = 10;  // Store the actual number 10 in the a variable
var b = a;   // Store a COPY of the actual number stored in a (10) in the b variable
a = 50;      // Change the actual data stored in a to 50 (no change to b here)
console.log("a is: " + a);  // 50
console.log("b is: " + b);  // 10

When you work with reference types, something a little different happens. Assigning a variable to a reference type means that the variable only holds a reference to the memory location where the object is actually stored, not the actual object itself. So, when you do this:

var a = {foo:"bar"};

a does not actually store the object itself, it only stores the memory location for where the object can be found (i.e. 0x3C41A).

But, as far as setting another variable equal to the first goes, it still works as it did with primitives - - a copy of what's in the first variable is made and given to the second variable.

Here's an example:

// An object is instantiated in memory and a is given the address of it (for example 0x3C41A)
var a = {}; 
 
// The contents of a (the memory location of an object) is COPIED into b.
// Now, both a and b hold the same memory location of the object (0x3C41A)
var b = a;

// Regardless of whether a or b is used, the same underlying object
// will be affected:
a.foo = "test";
console.log(b.foo); // "test"

// If one of the variables takes on a new value, it won't change
// what the other variable holds:
a = "something else";
console.log("a is: ", a);   // The new string primitive stored in memory
console.log("b is: ", b);   // The object stored in memory location (0x3C41A)

So, in your first tests, you've simply got two ways of accessing one object and then you change what a is holding (the memory location of the object) to a different object and therefore now you only have one way left to access the original object, through b.


If we try to "clear" a through by setting a = {}, object b will remain unchanged. I don't understand why manipulating an object in this way produces a different result than in the 1st example.

Because now we know that a = {} isn't clearing the object. It's just pointing a at something else.