🚀 JavaScript Fundamentals (Week-03): Understanding the Concepts That Every Developer Should Know
"Writing JavaScript code is one thing, but understanding what happens behind the scenes is what makes you a better developer."
When I first started learning JavaScript, I knew how to declare variables and write functions. However, I often found myself asking questions like:
- Why are there three ways to declare variables?
- What exactly is hoisting?
- How does JavaScript execute my code?
- Why can an inner function access variables from its parent function?
- What does the
thiskeyword actually refer to? - Why do developers keep talking about writing clean code?
This week, I focused on understanding these core JavaScript concepts instead of simply memorizing syntax.
In this article, I'll explain each concept in a beginner-friendly way with examples and practical explanations.
📚 Topics Covered
- Variables (
var,let,const) - Hoisting
- Lexical Scope
- Execution Context
- Call Stack
- Closures
-
thisBinding - DRY Principle
- KISS Principle
Let's start from the beginning.
📦 Variables in JavaScript
What is a Variable?
A variable is a named container used to store data in memory.
Instead of writing the same value repeatedly, we store it inside a variable and reuse it whenever required.
For example,
let name = "Sai";
console.log(name);
Enter fullscreen mode Exit fullscreen mode
Output
Sai
Enter fullscreen mode Exit fullscreen mode
Here,
-
let→ Variable declaration keyword -
name→ Variable name -
"Sai"→ Stored value
Why Do We Need Variables?
Imagine writing this:
console.log("Sai");
console.log("Sai");
console.log("Sai");
Enter fullscreen mode Exit fullscreen mode
If the value changes, every occurrence must be updated.
Using variables,
let name = "Sai";
console.log(name);
console.log(name);
console.log(name);
Enter fullscreen mode Exit fullscreen mode
Now changing one line updates every usage.
Variables improve:
- Readability
- Reusability
- Maintainability
Types of Variables
JavaScript provides three ways to declare variables.
- var
- let
- const
Although all three create variables, they behave differently.
var
var was introduced in the first version of JavaScript.
Characteristics:
- Function Scoped
- Can be redeclared
- Can be reassigned
- Hoisted
Example
var city = "Hyderabad";
var city = "Bangalore";
console.log(city);
Enter fullscreen mode Exit fullscreen mode
Output
Bangalore
Enter fullscreen mode Exit fullscreen mode
Because var allows redeclaration, it can accidentally overwrite existing values.
let
let was introduced in ES6.
Characteristics
- Block Scoped
- Cannot be redeclared
- Can be reassigned
Example
let age = 20;
age = 21;
console.log(age);
Enter fullscreen mode Exit fullscreen mode
Output
21
Enter fullscreen mode Exit fullscreen mode
const
const is used when the variable should not be reassigned.
Characteristics
- Block Scoped
- Cannot be redeclared
- Cannot be reassigned
const PI = 3.14;
console.log(PI);
Enter fullscreen mode Exit fullscreen mode
Output
3.14
Enter fullscreen mode Exit fullscreen mode
📈 Hoisting
What is Hoisting?
Hoisting is JavaScript's behavior of processing declarations before executing the code.
This doesn't mean the code physically moves. Instead, during the memory creation phase, JavaScript prepares variables and functions before execution begins.
Example
console.log(language);
var language = "JavaScript";
Enter fullscreen mode Exit fullscreen mode
Output
undefined
Enter fullscreen mode Exit fullscreen mode
Internally JavaScript treats it like this:
var language;
console.log(language);
language = "JavaScript";
Enter fullscreen mode Exit fullscreen mode
Variables declared using let and const are also hoisted, but they remain inside the Temporal Dead Zone (TDZ) until they are initialized.
🌍 Lexical Scope
Scope determines where a variable can be accessed.
Lexical Scope means an inner function can access variables declared in its outer function because of where it is written.
Example
function outer(){
let message="Hello";
function inner(){
console.log(message);
}
inner();
}
outer();
Enter fullscreen mode Exit fullscreen mode
Output
Hello
Enter fullscreen mode Exit fullscreen mode
JavaScript first searches inside inner(). If the variable isn't found, it looks in the outer function.
This searching process is called the Scope Chain.
⚙️ Execution Context
Before JavaScript executes any code, it creates an Execution Context.
Think of it as JavaScript's workspace.
It stores:
- Variables
- Functions
- Scope
- Value of
this
Every Execution Context has two phases.
Memory Creation Phase
During this phase,
- Variables are allocated memory.
-
varvariables are initialized withundefined. - Function declarations are stored.
Execution Phase
During this phase,
- Variables receive values.
- Statements execute one by one.
- Function calls create new execution contexts.
📚 Call Stack
The Call Stack keeps track of function execution.
It follows the Last In, First Out (LIFO) principle.
Example
function first(){
second();
}
function second(){
console.log("Inside Second");
}
first();
Enter fullscreen mode Exit fullscreen mode
Output
Inside Second
Enter fullscreen mode Exit fullscreen mode
Execution Flow
first()
↓
second()
↓
console.log()
↓
Return
↓
Return
Enter fullscreen mode Exit fullscreen mode
🔒 Closures
One of JavaScript's most powerful features is the Closure.
A Closure is created when an inner function remembers variables from its outer function even after the outer function has finished execution.
Example
function counter(){
let count = 0;
return function(){
count++;
console.log(count);
}
}
const increment = counter();
increment();
increment();
increment();
Enter fullscreen mode Exit fullscreen mode
Output
1
2
3
Enter fullscreen mode Exit fullscreen mode
Closures are commonly used for:
- Counters
- Data Privacy
- Event Handlers
- Module Pattern
🎯 Understanding this
The this keyword refers to the object that calls a function.
Its value depends on how the function is called.
Implicit Binding
const user = {
name:"Sai",
greet(){
console.log(this.name);
}
}
user.greet();
Enter fullscreen mode Exit fullscreen mode
Output
Sai
Enter fullscreen mode Exit fullscreen mode
Explicit Binding
JavaScript provides call(), apply(), and bind() to explicitly decide what this should refer to.
function greet(){
console.log(this.name);
}
const user={
name:"Sai"
};
greet.call(user);
Enter fullscreen mode Exit fullscreen mode
Output
Sai
Enter fullscreen mode Exit fullscreen mode
new Binding
function Student(name){
this.name=name;
}
const s1=new Student("Sai");
console.log(s1.name);
Enter fullscreen mode Exit fullscreen mode
Output
Sai
Enter fullscreen mode Exit fullscreen mode
Arrow Function
Arrow functions don't have their own this.
Instead, they inherit it from their surrounding scope.
✨ DRY Principle
DRY stands for
Don't Repeat Yourself
Instead of repeating code,
console.log("Welcome Sai");
console.log("Welcome Rahul");
Enter fullscreen mode Exit fullscreen mode
write
function greet(name){
console.log(`Welcome ${name}`);
}
greet("Sai");
greet("Rahul");
Enter fullscreen mode Exit fullscreen mode
Benefits
- Reusable code
- Easy maintenance
- Less duplication
💡 KISS Principle
KISS stands for
Keep It Simple, Stupid
Simple code is easier to understand than complicated code.
Instead of
function isEven(num){
if(num%2===0){
return true;
}
else{
return false;
}
}
Enter fullscreen mode Exit fullscreen mode
write
function isEven(num){
return num%2===0;
}
Enter fullscreen mode Exit fullscreen mode
Simple code is:
- Easy to debug
- Easy to maintain
- Easy to understand
🎯 Key Takeaways
After completing this week's learning, I understood that:
- Variables store data.
- Hoisting happens during memory creation.
- Lexical Scope decides where variables are accessible.
- Execution Context provides the environment for code execution.
- The Call Stack manages function execution.
- Closures preserve variables after a function finishes.
- The value of
thisdepends on how a function is called. - Following DRY and KISS helps write clean and maintainable code.
📝 Conclusion
Learning JavaScript isn't just about writing code—it's about understanding how the language works behind the scenes. Concepts like execution context, scope, closures, and this binding explain why our code behaves the way it does. By combining these fundamentals with clean coding principles like DRY and KISS, we can write code that is not only correct but also easy to read, maintain, and extend.
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.