During this learning session, I focused on JavaScript's internal working, including Execution Context, Variables, Scope, Closures, Hoisting, this binding, Call Stack, and Clean Code Principles like DRY and KISS.
- JavaScript Execution Context
The first topic I learned was Execution Context.
An Execution Context is the environment in which JavaScript executes code. Whenever JavaScript runs a script or calls a function, it creates an execution context.
Each execution context has two phases:
i)Memory Creation Phase
Before executing the code, JavaScript scans it and allocates memory.
During this phase:
var variables are initialized with undefined.
let and const are allocated memory but remain uninitialized (Temporal Dead Zone).
Function declarations are stored completely in memory.
Example:
console.log(a);
var a = 10;
Output:
undefined
Because var is initialized with undefined during the memory phase.
ii)Code Execution Phase
After memory allocation, JavaScript starts executing the code line by line.
Example:
var a = 10;
console.log(a);
Output:
10
- Variables in JavaScript
I learned the differences between var, let, and const.
a)var
-Function scoped
-Can be redeclared
-Can be reassigned
-Hoisted with undefined
b)let
Block scoped
Cannot be redeclared in the same scope
Can be reassigned
Exists in the Temporal Dead Zone before initialization
c)const
Block scoped
Cannot be redeclared
Cannot be reassigned
Must be initialized during declaration
- Lexical Scope
One important concept I learned is Lexical Scope.
Lexical Scope means a function can access variables from the scope where it was created.
Example:
let name = "Harshith";
function greet() {
console.log(name);
}
greet();
The function accesses name because it was created inside the same scope.
- Closures
A Closure is created when a function remembers variables from its outer scope even after the outer function has finished executing.
Example:
function counter() {
let count = 0;
return function () {
count++;
console.log(count);
};
}
const increment = counter();
increment();
increment();
increment();
Output:
1
2
3
The variable count remains available because of the closure.
Closures are commonly used to create private variables and implement the module pattern.
- Hoisting
Hoisting is JavaScript's behavior of moving declarations to the top of their scope before execution.
Example:
console.log(a);
var a = 10;
Output:
undefined
For let and const:
console.log(a);
let a = 10;
Output:
ReferenceError
because the variable is inside the Temporal Dead Zone until it is initialized.
- Understanding this Binding
One of the most interesting topics I learned was how JavaScript decides the value of this.
a)Default Binding
function greet() {
console.log(this);
}
greet();
In non-strict mode, this refers to the global object.
b)Implicit Binding
const person = {
name: "Harshith",
greet() {
console.log(this.name);
}
};
person.greet();
Here, this refers to person.
c)Explicit Binding
JavaScript allows us to manually set this using call(), apply(), and bind().
function greet(city) {
console.log(this.name, city);
}
const person = {
name: "Harshith"
};
greet.call(person, "Hyderabad");
d)new Binding
When a function is called using the new keyword, JavaScript creates a new object and binds this to it.
function Person(name) {
this.name = name;
}
const p = new Person("Harsh");
- Writing Better Code with DRY and KISS
Besides JavaScript internals, I also learned two important software engineering principles.
a)DRY (Don't Repeat Yourself)
Instead of repeating the same logic multiple times, create reusable functions.
This makes code easier to maintain.
b)KISS (Keep It Simple, Stupid)
Write simple, readable code instead of overly complex solutions.
Simple code is easier to understand, debug, and maintain.
Thank you for reading! If you're also learning JavaScript, I hope this summary helps you understand these core concepts more clearly. Happy coding!
Top comments (0)