Primitives and objects – what are they?
- primitives and
Primitive data types or primitives encapsulate 6 more subcategories, which are:
- null (special value) and
- undefined (special value).
Ok, so if these are the primitives, what are objects? Anything that is not a primitive value, is an object. Fair enough, right? Objects usually represent complex data types – they are structural types and include functions, arrays, and special non-data but structural types for any constructed object instance also used as data structures. The latter includes new Object, new Array, new Map, new Set, new WeakMap, new WeakSet, new Date, and almost everything made with new keyword.
As simple as that? Yep, as simple as that.
But what happens when we pass by value? That means that every time we assign some value to a variable, we also create a copy of that value, and this happens every single time. Again, it is best to look at an example. Let’s start by defining two variables – x and y:
let x = 5; let y = x; y = y + 3;
If we console.log(x), we get 5, and if we console.log(y), we get 8.
Later in the third line of the code (y = y + 3;) we change the variable y, but this change does not influence the value of a variable x.
What happens when we’re passing by reference?
The situation here is a bit different. When we create an object, we’re supplied with a reference to that object. So, if two variables hold the same values that are references to objects, in case we change the object, that change would reflect in both variables. This reflection of a change in both variables is quite different compared to passing by value when changing one variable does not affect the other.
Again, like before, it is best if we explain what happens when we pass by reference through a code example:
let a = ; let b = a; b.push(5); console.log(a); // [3, 5] console.log(b); // [3, 5]
In the first statement (let a = ;) we created an array, and we also defined a variable a, and we initialized the variable with a reference to the created array. So far, so good.
Then we said in the second line that let b = a; which means we defined a variable b, and we initialized variable b with the reference stored in variable a, and this is called passing by reference.
What happened in the third line of our code? b.push(5) changed our array by pushing an item 5, and because both a and b variables referenced the same array, we saw through the console.log that the mutation reflected in both a and b variables.
What if we want to compare values and references?
If we want to compare objects, it is important that we understand the difference between values and references. Why, you may ask. Well, if we’re using the strict comparison operator (triple equals ===), then two variables are equal only if they have the same value. Let’s take a look through an example:
let ten = 10; let tenCopy = 10; console.log(ten === tenCopy); // true console.log(ten === 10); // true console.log(ten === ten); // true
ten and tenCopy have the same value, and that is 10. The strict comparison operator (===) checks to see if the statement is true or false – in this case true as long as the value is 10 – and doesn’t really care where the value is taken from.
Ok, this was the case when we compared two values – but how does the strict comparison operator work when we compare references?
Two references are equal only if they reference exactly the same object. Let’s take a look at an example below:
// array1 and array2 hold references to different array instances let array1 = ; let array2 = ; console.log(array1 === array2); // false /* Why console.log(array1 === array2) results in false? array1 and array2 reference arrays of the same structure, however array1 === array2 evaluates to false because array1 and array2 reference different array objects. */ console.log(array1 === ); // false let array9 = array1; console.log(array1 === array9); // true console.log(array1 === array1); // true /* And this is the example when the strict comparison operator returns true - this happens only when we compare references pointing to the same object, in this case: array1 === array9 or array1 === array1. */
In conclusion – a difference between passing a value vs passing by reference
On the other hand, objects are passed as references and if we change an object, that change reflects in variables that are referenced to that object.
In the end, we played a bit with a strict comparison operator and we learned that it is different when we compare values and when we compare references. We learned that the two variables are equal if they only have the same values, but the two variables that hold references are equal only if they reference exactly the same object.