Javascript Objects vs Primitives

More javascript fundamentals today, I’ve been wanting to write about the differences between javascript objects and javascript primitives. Having a deep understanding about how objects and primitives behave can help level up your skills as a javascript front end developer. Not only that, if you’re working with Nodejs, the same concepts apply. So here we go.

Objects vs Primitives

First things first, let’s get this simple concept tucked deep inside our minds – “Objects (including functions) are stored and copied by reference, while primitives (strings, numbers, booleans) are always copied by value.”

To start lets declare some variables:


let philosopher = 'Georg Wilhelm Friedrich Hegel';
let category = philosopher;

console.log(philosopher);
console.log(category);

// Output:
// Georg Wilhelm Friedrich Hegel
// Georg Wilhelm Friedrich Hegel

Above, we observe that the output is the same for both philosopher and category. We cannot see it here, but under the hood both philosopher and category have their own assigned address in memory. In fact, we attempt to modify the philosopher variable here, the javascript engine will throw an error stating that the variable has already been declared. Thanks to the ‘let’ variable we are safeguarded from breaking this rule. In previous versions ES5, this was not the case making programs and memory management bug prone.

So, to recap primitives are completely independent of each other. However as we shall see with Objects (and functions) – these behave entirely different.


let philosopher = {
  name: 'Immanuel Kant',
  subject: 'Epistemology'
}

let category = philosopher;

console.log(philosopher);
console.log(category);

// Output: 
// { name: 'Immanuel Kant', subject: 'Epistemology' }
// { name: 'Immanuel Kant', subject: 'Epistemology' }

Alright at this point you might be thinking, primitives and objects behave exactly the same! Well, from what we can observe this is true at first glance. But now, let’s start playing around with our creations. Under the hood there are some interesting things lurking and for good reason.


let philosopher = {
  name: 'Immanuel Kant',
  subject: 'Epistemology'
}

let category = philosopher;

console.log(philosopher);
console.log(category);

// Output: 
// { name: 'Immanuel Kant', subject: 'Epistemology' }
// { name: 'Immanuel Kant', subject: 'Epistemology' }

// Assign name property with new value
philosopher.name = 'Rene Descartes';

console.log(philosopher); // references our original philosopher object
console.log(category); // references the philosopher object

// Output:
{ name: 'Rene Descartes', subject: 'Epistemology' }
{ name: 'Rene Descartes', subject: 'Epistemology' }

Above, we see that the philosopher object has been modified more specifically the property assigned to name. Note we have left the subject property untouched, therefore this remains the same.

So when we run our console.log() function to output the results – we see now that now both the philosopher and category objects contain the same updated name property values. Both objects point to the same memory address by reference rather than by value.

Important to keep in mind that functions are also objects, I have covered this in a separate post. With new ES6 features rolling out I wish to revisit functions though. So stay tuned!