JavaScript (JS) is a lightweight, interpreted, or just-in-time compiled programming language with first-class functions. It is best known as the scripting language for Web pages, but it's also used in many non-browser environments such as Node.js, mobile apps (React Native), and desktop apps (Electron).
It enables interactive web pages and is an essential part of web applications.
JavaScript code can be placed in HTML documents in three ways:
Code is written directly within an HTML tag using an event attribute (e.g., `onclick`, `onmouseover`).
<button onclick="alert('Hello from inline JS!');">Click Me</button>
Visual Example:
(Clicking this button will show an alert box.)
Code is placed within `<script>` tags inside the HTML document. Common for small scripts or when the script is specific to that page.
<!DOCTYPE html>
<html>
<head>
<title>Internal JS Example</title>
</head>
<body>
<h2 id="demo">Original Text</h2>
<script>
// Get the element by its ID
const element = document.getElementById('demo');
// Change its text content
element.textContent = 'Text changed by internal JS!';
// Log to console (check your browser's DevTools Console)
console.log('Internal JS executed!');
</script>
</body>
</html>
Visual Example (After page loads):
(The text above changes immediately on page load from "Original Text" to "Text changed by internal JS!". Check your browser console for "Internal JS executed!".)
Code is written in a separate `.js` file and linked to the HTML document using the `<script>` tag with the `src` attribute. This is the best practice for larger projects as it improves organization, caching, and maintainability.
<!DOCTYPE html>
<html>
<head>
<title>External JS Example</title>
</head>
<body>
<h2 id="extJsDemo">Text from HTML</h2>
<button id="extJsButton" class="js-example-button">Click for External JS</button>
<!-- Link to your external JavaScript file -->
<script src="script.js" defer></script>
</body>
</html>
And in your `script.js` file:
// script.js
document.addEventListener('DOMContentLoaded', function() {
const heading = document.getElementById('extJsDemo');
const button = document.getElementById('extJsButton');
if (button) {
button.addEventListener('click', function() {
if (heading) {
heading.textContent = 'Text changed by external JS!';
heading.style.color = 'blue';
}
console.log('Button clicked! External JS function triggered.');
});
}
console.log('External script.js loaded!');
});
Visual Example:
(The text above will change and turn blue when you click the button. Check your browser console for log messages.)
Variables are containers for storing data values. JavaScript has three keywords to declare variables: `var`, `let`, and `const`.
var oldVar = "Hello";
oldVar = "World"; // Re-assigned
var oldVar = "New Value"; // Re-declared (can lead to bugs)
let message = "Hi there!";
message = "Goodbye!"; // Re-assigned
// let message = "Another Hi!"; // Error: Cannot re-declare
const PI = 3.14159;
// PI = 3.14; // Error: Cannot re-assign a const
const USER_ID = 101; // Good for constants
JavaScript is a dynamically typed language, meaning you don't declare the type of a variable. It automatically determines the type when a value is assigned.
let greeting = "Hello, JavaScript!"; // String
let year = 2023; // Number
let price = 19.99; // Number
let isActive = true; // Boolean
let myVar; // Undefined
let emptyValue = null; // Null
let person = { name: "Alice", age: 30 }; // Object
let colors = ["red", "green", "blue"]; // Array (which is also an object)
console.log(typeof greeting); // Output: string
console.log(typeof year); // Output: number
console.log(typeof isActive); // Output: boolean
console.log(typeof myVar); // Output: undefined
console.log(typeof emptyValue); // Output: object (a quirk in JS)
console.log(typeof person); // Output: object
console.log(typeof colors); // Output: object (Arrays are objects)
Visual Example (Output to Browser Console):
Check the browser console (F12 > Console) after loading this page to see the `typeof` outputs.
Operators perform operations on values and variables.
let a = 10;
let b = 3;
console.log(a + b); // 13
console.log(a % b); // 1 (remainder)
console.log(a ** 2); // 100 (10 squared)
a++; // a is now 11
let x = 5;
x += 3; // x is now 8 (same as x = x + 3)
x *= 2; // x is now 16 (same as x = x * 2)
console.log(5 == "5"); // true (value only)
console.log(5 === "5"); // false (value and type)
console.log(10 > 5); // true
let isAdult = true;
let hasLicense = false;
console.log(isAdult && hasLicense); // false
console.log(isAdult || hasLicense); // true
console.log(!isAdult); // false
let age = 18;
let status = (age >= 18) ? "Adult" : "Minor";
console.log(status); // Adult
Visual Example (Output to Browser Console):
Check the browser console (F12 > Console) for the output of these operations.
Control flow statements dictate the order in which instructions are executed.
let temperature = 25;
if (temperature > 30) {
console.log("It's hot!");
} else if (temperature > 20) {
console.log("It's warm.");
} else {
console.log("It's cool.");
}
let day = "Monday";
switch (day) {
case "Monday":
console.log("Start of the week.");
break; // Important to break to prevent "fall-through"
case "Friday":
console.log("Almost weekend!");
break;
default:
console.log("Mid-week.");
}
for (let i = 0; i < 5; i++) {
console.log("Count: " + i);
}
let count = 0;
while (count < 3) {
console.log("Loop " + count);
count++;
}
const fruits = ["apple", "banana", "cherry"];
for (const fruit of fruits) {
console.log(fruit);
}
const personObj = { name: "Dave", age: 40 };
for (const key in personObj) {
console.log(key + ": " + personObj[key]);
}
Visual Example (Output to Browser Console):
Check the browser console (F12 > Console) for the output of these control flow examples.
Functions are reusable blocks of code that perform a specific task. They can take inputs (parameters) and return a value.
function add(a, b) {
return a + b;
}
console.log(add(5, 3)); // 8
const multiply = function(x, y) {
return x * y;
};
console.log(multiply(4, 2)); // 8
const subtract = (a, b) => a - b;
console.log(subtract(10, 4)); // 6
const greetUser = name => console.log(`Hello, ${name}!`);
greetUser("Charlie"); // Hello, Charlie!
const numbers = [1, 2, 3];
const doubled = numbers.map(num => num * 2); // map is a higher-order function
console.log(doubled); // [2, 4, 6]
Visual Example (Output to Browser Console):
Check the browser console for function outputs.
Arrays are ordered lists of values. They are zero-indexed, meaning the first element is at index 0.
const fruits = ["apple", "banana", "cherry"];
console.log(fruits[0]); // apple
console.log(fruits.length); // 3
// Common Array Methods
fruits.push("date"); // Adds to the end: ["apple", "banana", "cherry", "date"]
fruits.pop(); // Removes from the end: ["apple", "banana", "cherry"]
fruits.unshift("kiwi"); // Adds to the beginning: ["kiwi", "apple", "banana", "cherry"]
fruits.shift(); // Removes from the beginning: ["apple", "banana", "cherry"]
const index = fruits.indexOf("banana"); // 1
fruits.splice(index, 1); // Removes "banana": ["apple", "cherry"]
const citrus = fruits.slice(0, 1); // Creates a new array: ["apple"] (non-destructive)
fruits.forEach(fruit => console.log("I like " + fruit));
const newFruits = fruits.map(fruit => fruit.toUpperCase()); // ["APPLE", "CHERRY"]
const filteredFruits = fruits.filter(fruit => fruit.startsWith("a")); // ["apple"]
Visual Example (Output to Browser Console):
Check the browser console for array manipulation outputs.
Objects are collections of key-value pairs. They are fundamental for representing complex data.
const person = {
firstName: "Jane",
lastName: "Doe",
age: 28,
isStudent: false,
hobbies: ["reading", "hiking", "cooking"],
address: {
street: "123 Main St",
city: "Anytown"
},
// Method within an object
fullName: function() {
return this.firstName + " " + this.lastName;
}
};
// Accessing properties
console.log(person.firstName); // Jane
console.log(person["age"]); // 28
console.log(person.hobbies[1]); // hiking
console.log(person.address.city); // Anytown
console.log(person.fullName()); // Jane Doe
// Modifying properties
person.age = 29;
person.email = "jane.doe@example.com"; // Add new property
// Deleting properties
delete person.isStudent;
// Iterating over object properties
for (const key in person) {
if (typeof person[key] !== 'function') { // Exclude methods
console.log(`${key}: ${person[key]}`);
}
}
Visual Example (Output to Browser Console):
Check the browser console for object property access and iteration.
The Document Object Model (DOM) is a programming interface for web documents. It represents the page structure as a tree of objects. JavaScript can access and change all the elements on an HTML page.
<div id="domDemo" style="border: 1px solid #ccc; padding: 10px;">
<p>Original DOM content.</p>
</div>
<button id="changeDomBtn" class="js-example-button">Change DOM</button>
<button id="addRemoveBtn" class="js-example-button">Add/Remove Item</button>
<style>
.highlighted {
background-color: yellow;
font-weight: bold;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
const domDemoDiv = document.getElementById('domDemo');
const changeBtn = document.getElementById('changeDomBtn');
const addRemoveBtn = document.getElementById('addRemoveBtn');
let itemCount = 0;
changeBtn.addEventListener('click', function() {
domDemoDiv.innerHTML = '<h3>DOM Changed!</h3><p class="highlighted">New content with a highlight.</p>';
domDemoDiv.style.backgroundColor = '#e0f7fa'; // Change background style
});
addRemoveBtn.addEventListener('click', function() {
if (itemCount % 2 === 0) {
const newItem = document.createElement('p');
newItem.textContent = `Dynamically added item ${++itemCount}`;
newItem.style.color = 'blue';
domDemoDiv.appendChild(newItem);
} else {
if (domDemoDiv.lastChild && domDemoDiv.lastChild.nodeName === 'P') { // Ensure it's a paragraph
domDemoDiv.removeChild(domDemoDiv.lastChild);
itemCount--;
}
}
});
});
</script>
Visual Example:
Original DOM content.
(Click "Change DOM" to replace content. Click "Add/Remove Item" to dynamically add/remove paragraphs.)
JavaScript allows you to react to user actions or browser events (e.g., clicks, key presses, page load). This is done using event listeners.
<button id="myButton">Click me!</button>
<input type="text" id="myInput" placeholder="Type here...">
<p id="outputArea">Watch output here.</p>
<script>
document.addEventListener('DOMContentLoaded', function() {
const button = document.getElementById('myButton');
const input = document.getElementById('myInput');
const output = document.getElementById('outputArea');
// Add a click event listener
button.addEventListener('click', function() {
output.textContent = 'Button was clicked!';
});
// Add a keyup event listener
input.addEventListener('keyup', function() {
output.textContent = 'You typed: ' + input.value;
});
// Event object provides details about the event
input.addEventListener('keydown', function(event) {
console.log('Key pressed:', event.key, 'Code:', event.code);
});
});
</script>
Visual Example:
(Click the button or type in the input field to see the output change.)
JavaScript provides mechanisms to handle errors gracefully, preventing your script from crashing.
try {
// Code that might throw an error
let result = nonExistentVariable * 10; // This will cause an error
console.log(result);
} catch (error) {
// Code to handle the error
console.error("An error occurred:", error.message);
// You could display a user-friendly message here
// document.getElementById('errorDisplay').textContent = "Something went wrong!";
} finally {
// Code that runs regardless of whether an error occurred
console.log("Execution finished (try...catch block).");
}
function divide(a, b) {
if (b === 0) {
throw new Error("Cannot divide by zero!");
}
return a / b;
}
try {
console.log(divide(10, 2)); // 5
console.log(divide(10, 0)); // Throws an error
} catch (e) {
console.error("Caught custom error:", e.message);
}
Visual Example (Output to Browser Console):
Check the browser console to see how errors are caught and logged.
JavaScript is single-threaded, but it can handle operations that take time (like fetching data from a server) without blocking the main thread, using asynchronous patterns.
function fetchData(callback) {
setTimeout(() => {
const data = { message: "Data fetched!" };
callback(data);
}, 1000); // Simulate network delay
}
fetchData(function(data) {
console.log(data.message); // Data fetched! (after 1 second)
});
console.log("Request sent."); // This logs immediately
function fetchDataPromise() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const success = true; // Simulate success/failure
if (success) {
resolve({ message: "Promise data fetched!" });
} else {
reject("Failed to fetch data.");
}
}, 1000);
});
}
fetchDataPromise()
.then(data => console.log(data.message)) // Handles success
.catch(error => console.error("Promise Error:", error)) // Handles failure
.finally(() => console.log("Promise finished."));
console.log("Promise request sent.");
async function getAsyncData() {
try {
console.log("Fetching async data...");
const response = await fetchDataPromise(); // Await the promise to resolve
console.log("Async/Await:", response.message);
console.log("After await operation.");
} catch (error) {
console.error("Async/Await Error:", error);
}
}
getAsyncData();
console.log("Async function called.");
Visual Example (Output to Browser Console with delays):
Check the browser console (F12 > Console) to observe the sequence of logs for asynchronous operations.
(You'll see "Callback/Promise/Async function called immediately" logs first, followed by "Data fetched..." logs after their respective delays.)
ECMAScript 2015 (ES6) introduced many significant features that revolutionized JavaScript development. Subsequent versions (ES7, ES8, etc.) continue to add improvements.
const name = "Alice";
const greeting = `Hello, ${name}! You are ${2025 - 1995} years old.`;
console.log(greeting); // Hello, Alice! You are 30 years old.
const [first, second] = ["red", "green", "blue"];
console.log(first); // red
const { firstName, age } = { firstName: "Bob", lastName: "Smith", age: 35 };
console.log(firstName, age); // Bob 35
const arr1 = [1, 2];
const arr2 = [...arr1, 3, 4]; // [1, 2, 3, 4]
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }
function sum(first, ...restOfNumbers) {
console.log(first); // first argument
console.log(restOfNumbers); // array of remaining arguments
}
sum(10, 20, 30, 40); // 10, [20, 30, 40]
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hi, I'm ${this.name} and I'm ${this.age} years old.`);
}
}
const p = new Person("Eve", 25);
p.greet(); // Hi, I'm Eve and I'm 25 years old.
// utils.js
export const PI = 3.14;
export function add(a, b) { return a + b; }
// main.js
import { PI, add } from './utils.js';
console.log(PI); // 3.14
console.log(add(2, 3)); // 5
Visual Example (Output to Browser Console):
Check the browser console for ES6+ feature outputs.
JavaScript is a dynamic and powerful language that is constantly evolving. Mastering these fundamentals is the first step. From here, you can dive into advanced topics like Web APIs (Fetch API, Web Storage), advanced array/object methods, design patterns, and explore popular frameworks/libraries like React, Angular, or Vue.js to build complex and interactive web applications.