In Javascript there are 2 categories of data types:
1- Primitive data types:
All primitives are immutable (unchangeable) 🛌, there are 7 primitive data types:
-
Number: for numbers of any kind: integer or float. -
String: may have zero or more characters. -
Boolean: has only two values (true and false). -
Null: for unknown values – a standalone type that has a single valuenull. -
Undefined: for unassigned values – a standalone type that has a single valueundefined. -
Symbol: for unique identifiers. -
BigInt: is for integer numbers of arbitrary length.
2- Non-Primitive data type:
Non-primitive is mutable (changeable) 🦎, there is only one non-primitive data type:
-
Object: for more complex data structures.
Arrays and functions in JavaScript belong to the object data type.
Let's dive deeper into these data types
Look at this code, I will use a string (primitive) and an array (non-primitive).
var str = 'Berlin'
var arr = [1,2,3]
You can access the value inside them by the same way
console.log(str[0]) // 'B'
console.log(arr[0]) // 1
You can change array's item, like this..
arr[0] = 5
console.log(arr[0]) // 5
What about a string? can we do the same and change any char in this string?
str[0] = 'G'
console.log(str) // ??
So here is the point, you can't do that with string 🙅♂️.
Because a string is a primitive data type. And you can't change any primitive value.
str[0] = 'G'
console.log(str) // 'Berlin'
What about this case?
var city = 'Berlin'
city = 'Frankfurt'
console.log(city) // ??
The variable may be reassigned a new value, but the existing value can't be changed in the ways that objects, arrays, and functions. Immutability here doesn't make any effect, look how this happens..
Here we assign a brand new value 'Frankfurt', so there is no problem.
What about this case?
function square(x){
x = x * x
}
var num = 10
square(num)
console.log(num) // ??
In this case, square() will only ask, what the value of variable num? then it receives this value as argument.
So square() will not effect the value of num.
console.log(num) // 10
Now we are in objects phase, let's explore it.. 🔭
var num1 = 5, num2 = 5, obj1 = {}, obj2 = {};
console.log(num1 === num2) // ?
console.log(obj1 === obj2) // ?
In primitive data types, if we have 2 variables with the same value, so they both will pointing to this value, like this..
But with objects (non-primitive) it's different, every time we assign object {} to a variable, Javascript will create a brand new object value. The same goes for array, dates, functions and other objects, look how..
The image above explain us this answers.
console.log(num1 === num2) // true
console.log(obj1 === obj2) // false
Let's dive deeper in objects to see how they are mutable!
var car1 = {
model:'G 63',
brand: {
name: 'Mercedes'
}
}
var car2 = {
model:'GT 63 S',
brand: car1.brand
}
car2.model = 'GT Coupe'
car2.brand.name= 'Audi'
console.log(car1.model); // ?
console.log(car1.brand.name); // ?
console.log(car2.model); // ?
console.log(car2.brand.name); // ?
Let's break this problem down to figure out the answers..
1- First object's draw:
2- Second object's draw:
3- Then 2 changes:
As you saw, we can change the properties value within the object, this is called 'Mutation'.
console.log(car1.model); // "G 63"
console.log(car1.brand.name); // "Audi"
console.log(car2.model); // "GT Coupe"
console.log(car2.brand.name); // "Audi"
Well done, diver, you are in an interesting area. Go on.. 👏
var city = {
name:'München',
}
var _location = {
state:'Bavaria',
}
console.log(_location.name); // ?
Yes, as you said the answer is undefined, but how do we access property name from object location?
First off, let's see how the console prints the object.
var _location = {
state:'Bavaria',
}
console.log(_location);
Each object in Javascript by default contains a property called __proto__, so we will use this property to achieve our goal, as follows..
var _location = {
__proto__: city,
state:'Bavaria',
}
Now we will draw our visual explanation after this modification:
Based on this case, we can access name from location object, but we can't access state from city object.
console.log(_location.name); // 'München'
console.log(city.state); // undefined
Look at this example and try to get the answer.
var city = {
name:'München',
}
var _location = {
__proto__: city,
name:'Bavaria',
}
console.log(city.name); // ?
console.log(_location.name); // ?
The location object will look for a name property in the city object, only when it does not contain the required property name.
In this example, the location object has its own property name, so the city object will not be seen.
console.log(city.name); // 'München'
console.log(_location.name); // 'Bavaria'
Last interesting point about using __proto__
var humans = {}
var animals = {}
var plants = {}
humans.__proto__.need= 'Water'
console.log(humans.need); // 'Water'
console.log(animals.need); // 'Water'
console.log(plants.need); // 'Water'
As you saw if we add property need to __proto__ we can access the value of this property need from any other object.
This is where our diving trip ends 📍 I hope you have enjoyed and found it a useful trip. Wait for me on other exciting diving trips ✨.
Resources:
- just javascript a great email list (highly recommend course), explaining the basic principles of Javascript using mental models (illustrations in the article 👆) to explain how they work behind the scenes.
- MDN web docs.
- Javascript info.
- All illustrations were made using excalidraw.







Top comments (5)
Very useful article <3 .
Very interesting article. Thanks for sharing.
Thanks, you are welcome. 😃
Nice one! Reminds me of Dan Abramov's ideas on JavaScript mental models in justjavascript.com/ which I definitely recommend to anyone looking to expand on these ideas.
Thank you, of course it's an amazing way by Dan to understand these principles, and i have mentioned that at the bottom of the article.