DEV Community

Said Olano
Said Olano

Posted on

JavaScript: From Basics to Advanced (2026-09-03 23:37)

JavaScript: From Basics to Advanced

JavaScript is the backbone of modern web development. From simple interactive buttons to complex single-page applications, understanding JavaScript deeply is essential for any developer. This guide takes you from fundamental concepts to advanced techniques.

Table of Contents

  1. Getting Started
  2. Core Fundamentals
  3. Functions and Scope
  4. Objects and Prototypes
  5. Asynchronous JavaScript
  6. Advanced Patterns
  7. Best Practices

Getting Started

JavaScript is a dynamically typed, interpreted language that runs in browsers and on servers (via Node.js). You can start writing JavaScript immediately in your browser's console.

console.log("Hello, World!");
Enter fullscreen mode Exit fullscreen mode

Variables

Modern JavaScript uses let and const instead of the older var:

const name = "Alice";   // Cannot be reassigned
let age = 30;           // Can be reassigned
age = 31;               // Valid

// Avoid var due to function-scoping and hoisting quirks
Enter fullscreen mode Exit fullscreen mode

Core Fundamentals

Data Types

JavaScript has seven primitive types and one object type:

const string = "text";
const number = 42;
const boolean = true;
const nothing = null;
const notDefined = undefined;
const unique = Symbol("id");
const bigNumber = 9007199254740991n; // BigInt
const object = { key: "value" };
Enter fullscreen mode Exit fullscreen mode

Type Coercion

Understanding coercion prevents subtle bugs:

console.log(1 + "2");      // "12" (string concatenation)
console.log("5" - 2);      // 3   (numeric subtraction)
console.log(0 == false);   // true (loose equality)
console.log(0 === false);  // false (strict equality)
Enter fullscreen mode Exit fullscreen mode

Tip: Always prefer === over == to avoid unexpected coercion.

Functions and Scope

Function Declarations vs Expressions

// Declaration (hoisted)
function add(a, b) {
  return a + b;
}

// Expression (not hoisted)
const multiply = function (a, b) {
  return a * b;
};

// Arrow function
const subtract = (a, b) => a - b;
Enter fullscreen mode Exit fullscreen mode

Closures

Closures allow functions to retain access to their outer scope:

function createCounter() {
  let count = 0;
  return function () {
    count += 1;
    return count;
  };
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
Enter fullscreen mode Exit fullscreen mode

The inner function "closes over" the count variable, keeping it alive between calls.

Objects and Prototypes

Object Creation

const user = {
  name: "Bob",
  greet() {
    return `Hi, I'm ${this.name}`;
  },
};
Enter fullscreen mode Exit fullscreen mode

Prototypal Inheritance

JavaScript uses prototypes rather than classical inheritance:

class Animal {
  constructor(name) {
    this.name = name;
  }
  speak() {
    return `${this.name} makes a sound`;
  }
}

class Dog extends Animal {
  speak() {
    return `${this.name} barks`;
  }
}

const dog = new Dog("Rex");
console.log(dog.speak()); // "Rex barks"
Enter fullscreen mode Exit fullscreen mode

Under the hood, class is syntactic sugar over the prototype chain.

Asynchronous JavaScript

Promises

Promises represent eventual completion of asynchronous operations:

function fetchData(url) {
  return fetch(url)
    .then((response) => response.json())
    .catch((error) => console.error("Error:", error));
}
Enter fullscreen mode Exit fullscreen mode

Async/Await

A cleaner syntax built on top of Promises:

async function loadUser(id) {
  try {
    const response = await fetch(`/api/users/${id}`);
    const user = await response.json();
    return user;
  } catch (error) {
    console.error("Failed to load user:", error);
  }
}
Enter fullscreen mode Exit fullscreen mode

Handling Multiple Async Operations

// Run in parallel
const [users, posts] = await Promise.all([
  fetch("/api/users").then((r) => r.json()),
  fetch("/api/posts").then((r) => r.json()),
]);
Enter fullscreen mode Exit fullscreen mode

Advanced Patterns

Destructuring

const { name, age } = user;
const [first, ...rest] = [1, 2, 3, 4];
Enter fullscreen mode Exit fullscreen mode

Modules

// math.js
export const PI = 3.14159;
export function square(x) {
  return x * x;
}

// main.js
import { PI, square } from "./math.js";
Enter fullscreen mode Exit fullscreen mode

Higher-Order Functions

const numbers = [1, 2, 3, 4, 5];

const doubled = numbers.map((n) => n * 2);
const evens = numbers.filter((n) => n % 2 === 0);
const sum = numbers.reduce((acc, n) => acc + n, 0);
Enter fullscreen mode Exit fullscreen mode

Best Practices

  • Use const by default, let when reassignment is needed, avoid var.
  • Prefer immutability where possible to reduce side effects.
  • Handle errors gracefully with try/catch and Promise rejection handling.
  • Keep functions small and focused on a single responsibility.
  • Use meaningful names for variables and functions.
  • Leverage modern syntax like optional chaining (?.) and nullish coalescing (??):
const city = user?.address?.city ?? "Unknown";
Enter fullscreen mode Exit fullscreen mode

Top comments (0)