Since Node.js is literally JavaScript running on a server, a solid understanding of modern JavaScript (often referred to as ES6 or ECMAScript 2015+) is absolutely critical.
You don't need to know everything about JavaScript to get started, but there are a few core concepts you must be comfortable with to write effective Node.js applications.
let and constIn older JavaScript, variables were declared using var. Today, modern Node.js developers almost exclusively use let and const.
const: Used for variables that will never change (constants). let: Used for variables whose values will change over time.const serverPort = 3000; // serverPort = 8080; // This would cause an Error!let requestCount = 0; requestCount += 1; // This is perfectly fine console.log(requestCount); // Outputs: 1
Arrow functions provide a shorter, cleaner syntax for writing functions. You will see them everywhere in Node.js, especially when passing functions as arguments (callbacks).
// Traditional Function
function sayHello(name) {
return "Hello, " + name;
}
// Arrow Function
const sayHelloArrow = (name) => {
return Hello, ${name};
};
// Arrow Function (One-Liner)
const quickHello = name => Hello, ${name};
console.log(sayHello("Akash"));
console.log(sayHelloArrow("Riya"));
console.log(quickHello("Node"));
This is arguably the most important concept in Node.js. Node is designed to handle tasks without stopping (or blocking) the rest of the program. For example, reading a large file or fetching data from a database takes time. Instead of freezing the program while it waits, Node moves on to other code and comes back when the data is ready.
We handle this asynchronous behavior primarily using Promises and Async / Await.
A Promise represents the eventual completion (or failure) of an asynchronous operation.
const fetchUserData = () => {
return new Promise((resolve, reject) => {
// Simulating a database delay
setTimeout(() => {
resolve({ name: "John Doe", id: 101 });
}, 1000);
});
};
fetchUserData()
.then((user) => console.log("User found:", user))
.catch((error) => console.error("Error:", error));
Async/Await is "syntactic sugar" on top of promises. It makes asynchronous code look and behave a bit more like synchronous code, making it much easier to read.
const fetchUserData = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve({ name: "John Doe", id: 101 });
}, 1000);
});
};
const getUser = async () => {
try {
const user = await fetchUserData(); // Execution pauses here until the promise resolves
console.log("User found:", user);
} catch (error) {
console.error("Error:", error);
}
};
getUser();
Destructuring makes it easy to extract properties from objects or arrays and bind them to variables. This is heavily used when importing specific functions from Node.js modules.
const user = {
username: "akash123",
email: "akash@example.com",
role: "admin"
};
// Extracting properties the modern way
const { username, role } = user;
console.log(username); // Outputs: "akash123"
console.log(role); // Outputs: "admin"
Template literals allow you to embed expressions inside strings using backticks (`) and the ${} syntax. It eliminates the need for messy string concatenation.
const status = 200; const message = "OK";// The old way: // const log = "Status: " + status + " - " + message;
// The modern way: const log =
Status: ${status} - ${message};console.log(log);
Which keyword is used in modern JavaScript to define a variable whose value cannot be reassigned?