← Back to Articles

JavaScript Basics

Introduction

JavaScript brings web pages to life with interactivity. This article covers variables, data types, functions, control flow, DOM manipulation, and event handling.

What You'll Learn

  • Variables (let, const, var)
  • Data types and operators
  • Functions and arrow functions
  • Conditionals and loops
  • Arrays and objects
  • DOM manipulation
  • Event listeners

Variables

// let - block scoped, can be reassigned
let count = 0;
count = 1; // ✓ OK

// const - block scoped, cannot be reassigned
const PI = 3.14159;
// PI = 3; // ✗ Error!

// var - function scoped (avoid, use let/const)
var oldWay = 'deprecated';

// Block scope example
{
    let blockVar = 'inside';
    console.log(blockVar); // 'inside'
}
// console.log(blockVar); // ✗ ReferenceError

// Temporal Dead Zone
// console.log(x); // ✗ ReferenceError
let x = 5;

Data Types

// Primitives
const string = 'Hello';
const number = 42;
const float = 3.14;
const boolean = true;
const nullValue = null;
const undefinedValue = undefined;
const symbol = Symbol('id');

// Reference types
const array = [1, 2, 3];
const object = { name: 'John', age: 30 };
const date = new Date();
const regex = /pattern/g;

// Type checking
typeof 'hello'      // 'string'
typeof 42           // 'number'
typeof true         // 'boolean'
typeof {}           // 'object'
typeof []           // 'object' (gotcha!)
typeof null         // 'object' (historical bug)
typeof undefined    // 'undefined'

// Type coercion
'5' + 3      // '53' (string concatenation)
'5' - 3      // 2 (numeric subtraction)
'5' * '2'    // 10 (string to number)
!!'hello'    // true (to boolean)

Operators

// Arithmetic
5 + 3    // 8
5 - 3    // 2
5 * 3    // 15
5 / 3    // 1.666...
5 % 3    // 2 (remainder)
5 ** 2   // 25 (exponentiation)

// Comparison
5 === 5     // true (strict equality)
5 == '5'    // true (loose, avoids)
5 !== 3     // true (strict inequality)
5 > 3       // true
5 >= 5      // true

// Logical
true && false   // false (AND)
true || false   // true (OR)
!true           // false (NOT)

// Nullish coalescing
const name = userInput ?? 'Default';

// Optional chaining
const city = user?.address?.city;

Functions

// Function declaration (hoisted)
function greet(name) {
    return `Hello, ${name}!`;
}

// Function expression
const greet = function(name) {
    return `Hello, ${name}!`;
};

// Arrow function (ES6)
const greet = (name) => `Hello, ${name}!`;

// Multiple parameters
const add = (a, b) => a + b;

// Default parameters
const greet = (name = 'Guest') => `Hello, ${name}!`;

// Rest parameters
const sum = (...numbers) => numbers.reduce((a, b) => a + b, 0);
sum(1, 2, 3, 4); // 10

// Returning objects
const createUser = (name, age) => ({ name, age });

// IIFE (Immediately Invoked)
(() => {
    console.log('Runs immediately');
})();

Conditionals

// If/else
const age = 18;
if (age >= 18) {
    console.log('Adult');
} else if (age >= 13) {
    console.log('Teen');
} else {
    console.log('Child');
}

// Ternary operator
const status = age >= 18 ? 'adult' : 'minor';

// Switch statement
const day = 'Monday';
switch (day) {
    case 'Monday':
        console.log('Start of week');
        break;
    case 'Friday':
        console.log('End of week');
        break;
    default:
        console.log('Midweek');
}

// Truthy/Falsy
// Falsy: false, 0, '', null, undefined, NaN
// Everything else is truthy

if (userInput) { /* Runs if truthy */ }
if (!userInput) { /* Runs if falsy */ }

Loops

// For loop
for (let i = 0; i < 5; i++) {
    console.log(i);
}

// For...of (arrays, strings)
const colors = ['red', 'green', 'blue'];
for (const color of colors) {
    console.log(color);
}

// For...in (object keys)
const person = { name: 'John', age: 30 };
for (const key in person) {
    console.log(key, person[key]);
}

// While loop
let i = 0;
while (i < 5) {
    console.log(i);
    i++;
}

// Do...while
do {
    console.log(i);
    i++;
} while (i < 5);

// Break and continue
for (let i = 0; i < 10; i++) {
    if (i === 3) continue; // Skip 3
    if (i === 7) break;    // Stop at 7
    console.log(i);
}

Arrays

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

// Access
arr[0]        // 1
arr.at(-1)    // 5 (last element)

// Modify
arr.push(6);      // Add to end
arr.pop();        // Remove from end
arr.unshift(0);   // Add to start
arr.shift();      // Remove from start

// Transform
arr.map(x => x * 2);        // [2, 4, 6, 8, 10]
arr.filter(x => x > 2);     // [3, 4, 5]
arr.reduce((a, b) => a + b, 0); // 15

// Find
arr.find(x => x > 3);       // 4
arr.findIndex(x => x > 3);  // 3
arr.includes(3);            // true

// Other
arr.slice(1, 3);    // [2, 3] (doesn't modify)
arr.splice(1, 2);   // Removes 2 elements at index 1
arr.join(' - ');    // "1 - 2 - 3 - 4 - 5"
arr.reverse();      // Reverses array
arr.sort((a, b) => a - b); // Sort numbers

Objects

const person = {
    name: 'John',
    age: 30,
    greet() {
        return `Hi, I'm ${this.name}`;
    }
};

// Access
person.name;        // 'John'
person['age'];      // 30
person.greet();     // 'Hi, I'm John'

// Destructuring
const { name, age } = person;
const { name: fullName } = person; // Rename

// Spread operator
const updated = { ...person, age: 31 };

// Optional chaining
const city = person?.address?.city;

// Object methods
Object.keys(person);    // ['name', 'age']
Object.values(person);  // ['John', 30]
Object.entries(person); // [['name', 'John'], ['age', 30]]

// Check property
'name' in person;           // true
person.hasOwnProperty('name'); // true

DOM Manipulation

// Select elements
const el = document.getElementById('main');
const els = document.querySelectorAll('.item');
const first = document.querySelector('.item');

// Create element
const div = document.createElement('div');
div.textContent = 'Hello';
div.className = 'greeting';
div.id = 'greeting-1';

// Add to DOM
parent.appendChild(div);
parent.insertBefore(div, firstChild);

// Remove
div.remove();
parent.removeChild(div);

// Modify content
el.textContent = 'Text only';
el.innerHTML = 'HTML';

// Modify attributes
el.setAttribute('data-id', '123');
el.getAttribute('data-id');
el.removeAttribute('data-id');

// Modify classes
el.classList.add('active');
el.classList.remove('active');
el.classList.toggle('active');
el.classList.contains('active');

// Modify styles
el.style.color = 'red';
el.style.cssText = 'color: red; font-size: 16px;';

Event Handling

// Add event listener
const btn = document.querySelector('#myBtn');
btn.addEventListener('click', (event) => {
    console.log('Clicked!', event.target);
});

// Remove event listener
function handler(e) { console.log(e); }
btn.addEventListener('click', handler);
btn.removeEventListener('click', handler);

// Event object
element.addEventListener('click', (e) => {
    e.target;      // Element clicked
    e.currentTarget; // Element with listener
    e.preventDefault(); // Prevent default action
    e.stopPropagation(); // Stop bubbling
});

// Common events
element.addEventListener('submit', handleSubmit);
element.addEventListener('change', handleChange);
element.addEventListener('input', handleInput);
element.addEventListener('keydown', handleKey);
window.addEventListener('scroll', handleScroll);
window.addEventListener('load', handleLoad);

// Event delegation
document.querySelector('#list').addEventListener('click', (e) => {
    if (e.target.matches('.item')) {
        console.log('Item clicked:', e.target);
    }
});

Practical Example

<!-- HTML -->
<form id="todo-form">
    <input type="text" id="todo-input" placeholder="Add todo...">
    <button type="submit">Add</button>
</form>
<ul id="todo-list"></ul>

<script>
const form = document.getElementById('todo-form');
const input = document.getElementById('todo-input');
const list = document.getElementById('todo-list');

// Load from localStorage
let todos = JSON.parse(localStorage.getItem('todos')) || [];

function render() {
    list.innerHTML = todos.map((todo, i) => `
        <li>
            ${todo}
            <button onclick="removeTodo(${i})">×</button>
        </li>
    `).join('');
}

function addTodo(text) {
    todos.push(text);
    localStorage.setItem('todos', JSON.stringify(todos));
    render();
}

function removeTodo(index) {
    todos.splice(index, 1);
    localStorage.setItem('todos', JSON.stringify(todos));
    render();
}

form.addEventListener('submit', (e) => {
    e.preventDefault();
    const text = input.value.trim();
    if (text) {
        addTodo(text);
        input.value = '';
    }
});

render();
</script>

Key Takeaways

  • Use const by default, let when reassigning
  • Prefer arrow functions for callbacks
  • Use array methods (map, filter, reduce) over loops
  • Use querySelector for DOM selection
  • Use addEventListener for events
  • Practice event delegation for dynamic content

Next Steps

Continue your JavaScript journey with ES6+ features: