JavaScript for Complete Beginners: Your First Real Programs
Learn JavaScript from scratch -- variables, functions, arrays, DOM manipulation, and build an interactive project. No experience needed.
JavaScript is the language of the web. Every interactive thing you've ever done on a website -- clicking buttons, submitting forms, seeing content update without a page reload -- that's JavaScript. It runs in every browser, on every phone, and (with Node.js) on servers too. There's no escaping it if you want to build for the web.
The good news: JavaScript is genuinely approachable for beginners. You don't need to install anything special -- your browser already has a JavaScript engine built in. You can write your first program in the next sixty seconds.
This guide covers everything you need to go from zero to writing real, useful programs. We'll build up concepts one at a time and finish by building an interactive page from scratch.
Where JavaScript Runs
JavaScript runs in two main environments:
- The browser -- Chrome, Firefox, Safari, Edge all have JavaScript engines built in. This is where JS was born, and it's still the primary use case.
- Node.js -- a runtime that lets you run JavaScript outside the browser, on your computer or a server.
Your First JavaScript
Open your browser and press F12 (or Cmd+Option+J on Mac) to open Developer Tools. Click the "Console" tab. Type this:
console.log("Hello, world!");
Press Enter. You'll see Hello, world! printed below. That's it -- you just ran JavaScript.
console.log() is the function you'll use constantly for debugging. It prints whatever you give it to the console.
Variables: Storing Data
Variables are named containers for data. JavaScript has three ways to declare them:
let score = 0; // can be reassigned later
const name = "Alice"; // cannot be reassigned
var age = 25; // old way, avoid this
let vs const vs var
Useconst by default. If you know the value won't change, const communicates that clearly and prevents accidental reassignment.
Use let when the value needs to change. Loop counters, running totals, values that get updated -- these need let.
Avoid var. It's the original way to declare variables, but it has scoping quirks that cause bugs. There's no reason to use it in modern JavaScript.
const PI = 3.14159; // this will never change
let count = 0; // this will be incremented
count = count + 1; // works fine
PI = 3; // TypeError: Assignment to constant variable
Naming Rules
- Must start with a letter,
_, or$ - Can contain letters, numbers,
_,$ - Case-sensitive (
scoreandScoreare different variables) - Convention: use
camelCasefor variables and functions (userName,totalPrice)
Data Types
JavaScript has a handful of basic data types you'll work with constantly:
Strings
Text, wrapped in quotes:
const greeting = "Hello, world";
const name = 'Alice';
const message = Welcome, ${name}!; // template literal -- note the backticks
Template literals (backtick strings) let you embed expressions with ${}. Use them whenever you need to combine strings with variables.
Common string methods:
const text = "JavaScript is awesome";
text.length; // 21
text.toUpperCase(); // "JAVASCRIPT IS AWESOME"
text.toLowerCase(); // "javascript is awesome"
text.includes("Script"); // true
text.indexOf("is"); // 11
text.slice(0, 10); // "JavaScript"
text.split(" "); // ["JavaScript", "is", "awesome"]
text.trim(); // removes whitespace from both ends
Numbers
JavaScript has one number type for both integers and decimals:
const age = 25;
const price = 19.99;
const negative = -10;
// Arithmetic
console.log(10 + 3); // 13
console.log(10 - 3); // 7
console.log(10 * 3); // 30
console.log(10 / 3); // 3.3333...
console.log(10 % 3); // 1 (remainder)
console.log(10 ** 3); // 1000 (exponentiation)
Booleans
True or false:
const isLoggedIn = true;
const hasPermission = false;
// Comparison operators return booleans
console.log(5 > 3); // true
console.log(5 === 3); // false
console.log(5 !== 3); // true
Always use === (strict equality) instead of == (loose equality). Loose equality does type coercion that leads to bizarre results: "" == 0 is true, "0" == false is true. Strict equality avoids all of that.
null and undefined
let result; // undefined -- declared but no value assigned
const data = null; // null -- explicitly "no value"
undefined means "this variable exists but hasn't been given a value." null means "I intentionally set this to nothing." In practice, use null when you want to explicitly represent emptiness.
Operators
Beyond arithmetic, you'll use these constantly:
// Assignment
let x = 10;
x += 5; // x = x + 5 -> 15
x -= 3; // x = x - 3 -> 12
x = 2; // x = x 2 -> 24
x++; // x = x + 1 -> 25
x--; // x = x - 1 -> 24
// Logical operators
true && true; // true (AND -- both must be true)
true || false; // true (OR -- at least one must be true)
!true; // false (NOT -- flips the value)
// Ternary operator (inline if/else)
const status = age >= 18 ? "adult" : "minor";
Conditionals: Making Decisions
if / else if / else
const temperature = 28;
if (temperature > 30) {
console.log("It's hot outside");
} else if (temperature > 20) {
console.log("Nice weather");
} else if (temperature > 10) {
console.log("A bit chilly");
} else {
console.log("It's cold");
}
switch
Useful when checking one variable against many specific values:
const day = "Monday";
switch (day) {
case "Monday":
case "Tuesday":
case "Wednesday":
case "Thursday":
case "Friday":
console.log("Weekday");
break;
case "Saturday":
case "Sunday":
console.log("Weekend");
break;
default:
console.log("Invalid day");
}
Don't forget break -- without it, execution falls through to the next case.
Loops: Repeating Things
for loop
for (let i = 0; i < 5; i++) {
console.log(Iteration ${i});
}
// Prints: Iteration 0, Iteration 1, ... Iteration 4
The three parts: initialization (let i = 0), condition (i < 5), update (i++).
while loop
let count = 0;
while (count < 5) {
console.log(count);
count++;
}
Use while when you don't know in advance how many iterations you need.
for...of loop
The cleanest way to iterate over arrays:
const colors = ["red", "green", "blue"];
for (const color of colors) {
console.log(color);
}
Functions
Functions are reusable blocks of code. They're how you organize your programs.
Function Declaration
function greet(name) {
return Hello, ${name}!;
}
console.log(greet("Alice")); // "Hello, Alice!"
Function Expression
const greet = function(name) {
return Hello, ${name}!;
};
Arrow Functions
The modern, concise syntax:
const greet = (name) => {
return Hello, ${name}!;
};
// Even shorter for single expressions:
const greet = (name) => Hello, ${name}!;
// Single parameter doesn't need parentheses:
const double = n => n * 2;
Arrow functions are the standard in modern JavaScript. Use them unless you have a specific reason not to.
Parameters and Return Values
Functions can take multiple parameters and return a value:
function calculateTax(price, taxRate = 0.1) {
const tax = price * taxRate;
return tax;
}
console.log(calculateTax(100)); // 10 (uses default 0.1)
console.log(calculateTax(100, 0.2)); // 20 (uses provided 0.2)
If a function doesn't explicitly return something, it returns undefined.
Arrays
Arrays are ordered lists of values:
const fruits = ["apple", "banana", "cherry"];
// Access by index (starts at 0)
console.log(fruits[0]); // "apple"
console.log(fruits[2]); // "cherry"
console.log(fruits.length); // 3
Essential Array Methods
These are the ones you'll use every day:
const numbers = [1, 2, 3, 4, 5];
// Add and remove
numbers.push(6); // add to end -> [1,2,3,4,5,6]
numbers.pop(); // remove from end -> [1,2,3,4,5]
numbers.unshift(0); // add to start -> [0,1,2,3,4,5]
numbers.shift(); // remove from start -> [1,2,3,4,5]
// Find
numbers.includes(3); // true
numbers.indexOf(3); // 2
numbers.find(n => n > 3); // 4 (first match)
// Transform (these return NEW arrays)
const doubled = numbers.map(n => n * 2); // [2,4,6,8,10]
const evens = numbers.filter(n => n % 2 === 0); // [2,4]
const sum = numbers.reduce((acc, n) => acc + n, 0); // 15
// Iterate
numbers.forEach(n => console.log(n));
map, filter, and reduce are the most important. map transforms each element, filter selects elements matching a condition, and reduce combines all elements into a single value.
Objects
Objects store key-value pairs:
const user = {
name: "Alice",
age: 28,
email: "alice@example.com",
isAdmin: false,
};
// Access properties
console.log(user.name); // "Alice"
console.log(user["email"]); // "alice@example.com"
// Modify
user.age = 29;
user.phone = "555-1234"; // adds a new property
// Delete
delete user.phone;
// Check if property exists
console.log("name" in user); // true
Destructuring
A shorthand for extracting values:
const { name, age, email } = user;
console.log(name); // "Alice"
console.log(age); // 28
This works with arrays too:
const [first, second, third] = ["a", "b", "c"];
console.log(first); // "a"
The DOM: Making Pages Interactive
The DOM (Document Object Model) is the browser's representation of your HTML page as a tree of objects. JavaScript can read and modify this tree, which is how you make pages interactive.
Selecting Elements
// Select by ID
const header = document.getElementById("main-header");
// Select by CSS selector (returns first match)
const button = document.querySelector(".submit-btn");
// Select all matches
const items = document.querySelectorAll(".list-item");
querySelector and querySelectorAll are the most flexible -- they accept any CSS selector.
Modifying Elements
const title = document.querySelector("h1");
// Change text
title.textContent = "New Title";
// Change HTML content
title.innerHTML = "New <em>Title</em>";
// Change styles
title.style.color = "blue";
title.style.fontSize = "2rem";
// Add/remove CSS classes
title.classList.add("highlighted");
title.classList.remove("hidden");
title.classList.toggle("active");
// Change attributes
const link = document.querySelector("a");
link.setAttribute("href", "https://example.com");
Event Listeners
This is where interactivity happens:
const button = document.querySelector("#my-button");
button.addEventListener("click", function() {
console.log("Button was clicked!");
});
You can listen for any DOM event: click, input, change, keydown, submit, mouseover, scroll, and dozens more.
const input = document.querySelector("#search");
input.addEventListener("input", function(event) {
console.log("Current value:", event.target.value);
});
Creating and Removing Elements
// Create a new element
const newItem = document.createElement("li");
newItem.textContent = "New item";
// Add it to the page
const list = document.querySelector("ul");
list.appendChild(newItem);
// Remove an element
newItem.remove();
Build: Interactive Character Counter
Let's build a real project that uses everything we've covered. Create an HTML file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Character Counter</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: system-ui, sans-serif;
max-width: 600px;
margin: 2rem auto;
padding: 1rem;
}
h1 { margin-bottom: 1rem; }
textarea {
width: 100%;
height: 150px;
padding: 0.75rem;
font-size: 1rem;
border: 2px solid #d1d5db;
border-radius: 8px;
resize: vertical;
}
textarea:focus { outline: none; border-color: #2563eb; }
.stats {
display: flex;
gap: 1.5rem;
margin-top: 1rem;
flex-wrap: wrap;
}
.stat {
background: #f3f4f6;
padding: 0.75rem 1.25rem;
border-radius: 8px;
}
.stat-value {
font-size: 1.5rem;
font-weight: bold;
color: #2563eb;
}
.stat-label { font-size: 0.85rem; color: #6b7280; }
.warning { color: #dc2626; }
.limit-bar {
height: 6px;
background: #e5e7eb;
border-radius: 3px;
margin-top: 0.5rem;
overflow: hidden;
}
.limit-fill {
height: 100%;
background: #2563eb;
border-radius: 3px;
transition: width 0.2s, background 0.2s;
}
.limit-fill.danger { background: #dc2626; }
</style>
</head>
<body>
<h1>Character Counter</h1>
<textarea id="text-input" placeholder="Start typing..."></textarea>
<div class="limit-bar">
<div class="limit-fill" id="limit-fill"></div>
</div>
<div class="stats">
<div class="stat">
<div class="stat-value" id="char-count">0</div>
<div class="stat-label">Characters</div>
</div>
<div class="stat">
<div class="stat-value" id="word-count">0</div>
<div class="stat-label">Words</div>
</div>
<div class="stat">
<div class="stat-value" id="sentence-count">0</div>
<div class="stat-label">Sentences</div>
</div>
<div class="stat">
<div class="stat-value" id="reading-time">0</div>
<div class="stat-label">Sec to read</div>
</div>
</div>
<script>
const MAX_CHARS = 280;
// Select elements
const textInput = document.querySelector("#text-input");
const charCount = document.querySelector("#char-count");
const wordCount = document.querySelector("#word-count");
const sentenceCount = document.querySelector("#sentence-count");
const readingTime = document.querySelector("#reading-time");
const limitFill = document.querySelector("#limit-fill");
function countWords(text) {
const trimmed = text.trim();
if (trimmed === "") return 0;
return trimmed.split(/\s+/).length;
}
function countSentences(text) {
const trimmed = text.trim();
if (trimmed === "") return 0;
const sentences = trimmed.split(/[.!?]+/).filter(s => s.trim().length > 0);
return sentences.length;
}
function calculateReadingTime(wordCount) {
// Average reading speed: 200 words per minute
const minutes = wordCount / 200;
return Math.ceil(minutes * 60);
}
function updateStats() {
const text = textInput.value;
const chars = text.length;
const words = countWords(text);
const sentences = countSentences(text);
const time = calculateReadingTime(words);
// Update displays
charCount.textContent = chars;
wordCount.textContent = words;
sentenceCount.textContent = sentences;
readingTime.textContent = time;
// Update progress bar
const percentage = Math.min((chars / MAX_CHARS) * 100, 100);
limitFill.style.width = percentage + "%";
// Color warning when approaching limit
if (chars > MAX_CHARS) {
charCount.classList.add("warning");
limitFill.classList.add("danger");
} else {
charCount.classList.remove("warning");
limitFill.classList.remove("danger");
}
}
// Listen for input events
textInput.addEventListener("input", updateStats);
</script>
</body>
</html>
Save this as counter.html and open it in your browser. You'll have a working character counter that updates in real time as you type.
What This Project Covers
- Variables --
constfor elements and config,letisn't needed here since we recalculate everything - Functions --
countWords,countSentences,calculateReadingTime,updateStats - Strings --
.trim(),.split(),.length - Arrays --
.filter()to clean up empty splits - Conditionals -- checking against
MAX_CHARSfor the warning state - DOM manipulation --
querySelector,textContent,style,classList - Event listeners --
addEventListener("input", ...)for real-time updates
Common Mistakes Beginners Make
Using== instead of ===. Loose equality does weird type coercion. 0 == "" is true. null == undefined is true. Just use === and avoid the entire category of bugs.
Forgetting that arrays and objects are references. When you do const b = a where a is an array, both a and b point to the same array. Modifying b also modifies a. Use spread ([...a]) or structuredClone(a) to make a copy.
Not understanding asynchronous code. setTimeout, fetch, and event listeners don't execute immediately. They schedule code to run later. If you write code after a setTimeout expecting the timeout to have run, it won't have.
Declaring variables in the wrong scope. Variables declared with let and const inside a {} block are only accessible inside that block. This is usually what you want, but it surprises beginners who expect them to be available outside.
Not handling edge cases in string operations. Splitting an empty string by spaces gives [""], not []. Always check for empty input before processing.
What's Next
You've got the fundamentals down. Here's where to go from here:
- Async JavaScript --
Promises,async/await, andfetchfor working with APIs - ES6+ features -- destructuring, spread operator, optional chaining, nullish coalescing
- A framework -- React, Vue, or Svelte to build complex single-page applications
- Node.js -- run JavaScript on the server, build APIs, use npm packages
- TypeScript -- adds type checking to JavaScript, catches bugs before runtime
For more JavaScript tutorials and project guides, check out CodeUp.