JavaScript Fundamentals: A Simplified Guide
Simplifying JavaScript Fundamentals for Easy Understanding
Introduction
I finished the course Just JavaScript by Dan Abramov.
In this blog post, I wanna share things I've learned.
Mental Models
Mental models make code easier to understand.
They are simplified versions of how we think code works, therefore helping us work with code more effectively.
let x = 10;
let y = x;
x = 0;
Here's what happens:
We set a variable called
x
to 10.Then, we create another variable called
y
and give it the same value asx
.After that, we change the value of
x
to 0.
In our thoughts, it goes like this:
x
equals 10.Then we make
y
equal tox
, which meansx
is also 10.Later, we change the value of
x
to 0.So now,
x
is 0 andy
is still 10.
Values and code
In JavaScript, values and code exist independently. There are two categories of values:
Primitive Values
Objects and Functions
Expressions in JavaScript are like questions we ask in our code. They don't show values on their own, but JavaScript gives us the answers. For example, when we ask 2 + 2
, the answer is 4.
The typeof
operator allows us to check the type of a value:
console.log(2 + 2); // 4
console.log(typeof(2)); // "number"
console.log(typeof({})); // "object"
console.log(typeof([])); // "object"
console.log(typeof(x => x * 2)); // "function"
console.log(typeof("hello")); // "string"
console.log(typeof(undefined)); // "undefined"
Primitive Values
Primitive values in JavaScript have always existed, and we cannot create new primitive types. They are immutable, which means they cannot be changed once created.
Undefined: Represents an undefined or unknown value.
let x;
console.log(variable); // undefined
// Variable has no value yet.
Null: Represents the absence of a value.
let value = null;
console.log(value); // null
// Variable intentionally has no value.
Boolean: Represents true or false.
let isWaterWet = true;
let isFireWet = !isWaterWet;
console.log(isWaterWet); // true
console.log(isFireWet); // false
Numbers: Represent numerical values.
let number = 28;
console.log(number); // 28
NaN: Stands for "Not a Number" and represents an invalid numeric value.
let result = "Hello" / 2;
console.log(result); // NaN
BigInts: Handles large whole numbers.
let bigNumber = 12345678901234567890n;
console.log(bigNumber); // 12345678901234567890n
String: Represents text.
let world = "Shinobi World";
console.log(world); // "Shinobi World"
Objects and Functions
Objects
Objects let us create our own values. They can be arrays, dates, and other non-primitive types. We can change them because they're mutable.
When we use {}
in JavaScript, it makes a new object every time. So, even if we use {}
more than once, each one will be its own separate object.
let anime = {};
let manga = {};
console.log(anime === manga); // false (not the same object)
Functions
Functions are special and can be thought of as objects. We use parentheses ()
after their name to call functions, and they execute their code, which might give us a result.
function jutsu() {
console.log('Shadow Clones');
}
jutsu(); // Calling the function
Functions can be changed, so we can make them behave differently or redefine them.
let multiply = function (a, b) {
return a * b;
};
multiply = function (a, b) {
return a + b;
};
console.log(multiply(2, 3)); // 5
When a function runs, it creates a new function value.
for (let i = 0; i < 7; i++) {
console.log({});
}
/* The line of code console.log({}) creates a brand new object every time it is executed within the loop. */
Equality of Values
Strict Equality (===): checks the value and the type of the compared values.
console.log(2 === 2); // true
console.log("Boruto" === "Boruto"); // true
Loose Equality (==): checks only the value of the compared values.
- Before comparing values, JavaScript does type coercion, which means it converts a value from one type to another.
console.log(2 == "2"); // true
/* True because `==` changes the text '2' into the number 2 and then checks if they are the same */
Same Value Equality - Object.is(): a way to compare two values
console.log(Object.is(2, 2)); // true
console.log(Object.is({}, {})); // false
/* False because each {} creates a new object with a different memory reference */
Properties in JavaScript
Properties are data that belong to objects and are grouped together. Each property always directly points to a value and cannot reference another property or a variable.
let boruto = { surname: 'Uzumaki', age: 16 };
console.log(boruto.age); // 64
console.log(boruto.power); // undefined
/* Returns undefined because there is no "power" property defined in the boruto object */
They must have unique names within an object, and they are case-sensitive. This means having properties with the same or similar names but different casing will result in separate and independent properties.
const character = { name: 'Boruto Uzumaki', age: 16, Age: 0 };
console.log(character.name); // "Boruto Uzumaki"
console.log(character.age); // 16
console.log(character.Age); // 0
Mutation
Objects can be put inside other objects. Changing a property of an object is called mutation and it changes the object itself.
const character = { name: 'Boruto Uzumaki', age: 16};
character.age = 4;
console.log(character.age); // 4
Using const
to declare a variable stops us from changing what it refers to, but we can still modify an object's properties through object mutation.
Prototypes
Prototypes help us share features between objects. But if we change a feature in one object, it won't affect its prototype. They are key to creating classes and inheritance in JavaScript.
const boruto = { jutsu: 'Shadow Clones' };
const mitsuki = { __proto__: boruto, age: 19 };
console.log(mitsuki.jutsu); // 'Shadow Clones'
Prototype chaining in JavaScript is like creating a family tree for objects, where they can share and get traits from their parents and grandparents:
const sarada = {
strong: true
};
const boruto = { __proto__: sarada, jutsu: 'Shadow Clones' };
let mitsuki = {
__proto__: boruto,
age: 19
};
console.log(mitsuki.strong); // true
The hasOwnProperty
method checks if an object has its own property, not considering the prototype chain, and only considers properties directly defined on the object.
const boruto = { jutsu: 'Shadow Clones' };
const mitsuki = { __proto__: boruto, age: 19 };
console.log(mitsuki.hasOwnProperty('jutsu')); // false
console.log(mitsuki.hasOwnProperty('age')); // true
Review
I wish I had done this course earlier.
I strongly recommend it to anyone who wants to dive deeper into JavaScript.