I like to think of JavaScript variables as sticky notes. A sticky note is a small note which you put on your fridge. What can you write on your sticky note? You can write small pieces of information.
Now there are two types of information in JavaScript - primitive values and reference values. Primitive values are small pieces of information that you can write on your sticky note directly. They include:
- Booleans
- Numbers
- Strings
- Null
- Undefined
On the other hand reference values are large amounts of information which you can't write on a small sticky note. So how do you store reference values in sticky notes?
You don't.
Reference values (like arrays, objects and functions) are written on a bigger piece of paper and only a reference to them is written on the sticky note. For example, my wife might write:
Honey, the list of groceries is under your keyboard.
Here the list of groceries is an array (i.e. a large amount of information). Since we can't write it on a small sticky note we simply write it on a bigger piece of paper and make a sticky note which tells us where it is to be found. In programming terms:
var groceryList = ["1 apple", "2 bananas", "3 loaves of bread"];
Here the actual grocery list is stored somewhere in memory and only the address of the grocery list is stored in the variable groceryList.
So what happens when we assign one variable to another? Let's first take an example of a primitive value:
var x = 2;
var y = x;
alert(y);  // 2
y = 3;
alert(x);  // 2
This is what's happening:
- We write the number 2on a new sticky note and put it on our fridge.
- We copy the number 2from the sticky notexonto another sticky noteyand put it on our fridge.
- We erase the value of sticky note yand write the number3on it instead.
- Now the value of sticky note xis2and sticky noteyis3.
This is called copy by value because we're just copying the value of sticky note x onto sticky note y.
Now let's take an example of copy by reference. In fact let's take your example of copy by reference:
var objA = {a: 1};
var objB = objA;
objA.a = 2;
objB.a; // 2
Here's what's happening in your example:
- We create an object {a: 1}somewhere in memory and write the address of this object on sticky noteobjA. Let's call this addressxfor simplicity's sake.
- We copy the address xfrom sticky noteobjAonto another sticky noteobjB. Now bothobjAandobjBreference the same object{a: 1}stored at memory locationx.
- Hence when we change the value of objA.athe same change is reflected onobjB.abecauseobjAandobjBboth reference the same object stored at memory locationx.
This is called copy by reference because we are simply copying the reference of an object from sticky note objA to sticky note objB. We're not copying the actual object.
So what's the difference between copy by reference and copy by value? Absolutely nothing. In both cases we're simply copying the value of one sticky note onto another.
Two sticky notes are said to be equivalent only when they contain the exact same information. For example the following are equivalent:
var x = 2;
var y = 2;
alert(x === y); // true
var o = {a: 1};
var p = o;
alert(o === p); // true
However the following values are not equivalent:
var o = {a: 1};
var p = {a: 1};
alert(o === p); // false
The reason that they are not equivalent is because o points to an object stored at a memory location say x while p points to an object stored at a different memory location say y. Although both these objects have the exact same properties they are in fact two different objects.
For example no two Nintendo Gameboys are the same no matter how identical they look. In the same spirit let's take a look at your last example:
var objA = {a: 1};
var objB = objA;
objA = {a: 2};  //Assigned whole object here instead property.
objB.a; //1 - Shouldn't this be 2 ??
Here's what happening in the above code:
- We create an object {a: 1}at a memory locationxand write the addressxon a sticky noteobjA.
- We copy the address xfrom sticky noteobjAto sticky noteobjB. Both of them now point to the same object stored at memory locationx.
- We create a new object {a: 2}at a memory locationyand write the addressyon the stick noteobjA. NowobjAhas a reference valueyandobjBhas a reference valuex. They reference two different objects.
As you can see assigning a new reference value to objA simply overwrites the old reference value. It does not replace the object {a: 1} with the object {a: 2}. That's not possible in JavaScript.