JavaScript (Introduction)
JavaScript is the language of the browser. HTML is the structure, CSS is the look, and JavaScript is the behavior: it changes the page and reacts to what the user does. This topic covers the basics of the language first, then uses them to change the page through the DOM and to respond to events.
Key focus points
Where JavaScript goes
- JavaScript runs in the browser. The browser reads your script and runs it top to bottom, one statement at a time.
- Add it with a <script> tag. Inline: <script>console.log("hi")</script>. In a separate file: <script src="app.js"></script>. Use the separate file, for the same reason you use a separate stylesheet.
- Put the <script> at the end of the <body>, or in the <head> with defer: <script src="app.js" defer></script>. Either way the HTML is ready before the script looks for elements in it.
- console.log(value) prints to the console. Open it with F12 (Cmd + Option + J on a Mac) and keep it open while you work. Errors show up there in red, with the file and the line number.
- When a line throws an error, the script stops there. Nothing after it runs.
- Comments: // for one line, /* ... */ for several. A semicolon ends a statement.
Try it: pick an example, edit the code and press Run. The output appears in the console on the right, just like the one in DevTools.
- Hello from JavaScript
- 5
- The answer is 42
Variables: automatically, var, let and const
- A variable is a name for a value. Declare it once, then use the name.
- const: the variable cannot be given a new value. Use it by default.
- let: the value can change: let score = 0; then score = 10. Both const and let exist only inside the block { } where they are declared.
- var: the old way. It ignores blocks, it can be declared twice, and it is hoisted: you can use it before the line that declares it and get undefined instead of an error. Do not use it in new code.
- Automatically: x = 5 with no keyword creates a global variable, usually by accident, from a typo. In strict mode ('use strict' at the top of the file) it is an error instead, which is what you want.
- const does not freeze an object or an array. You cannot point the variable at a new value, but you can change what is inside: const list = []; list.push(1) works.
- Names use letters, digits, _ and $, and cannot start with a digit. Write them in camelCase: firstName, totalPrice. Case matters: total and Total are two different variables.
Try it: run each example and read the errors. Each one is something JavaScript protects you from, or something var lets slip through.
- 15
- 3.14
- Uncaught TypeError: Assignment to constant variable.
Data types
- Seven primitive types: String ('text'), Number (42, 3.14), BigInt (10n), Boolean (true, false), Undefined, Null and Symbol. Everything else is an Object, including arrays and functions.
- Number covers whole numbers and decimals. 0.1 + 0.2 is 0.30000000000000004, so round with toFixed(2) before you show a price.
- NaN means "not a number", the result of math that makes no sense, like 'abc' * 2. Dividing by 0 gives Infinity.
- BigInt is for whole numbers bigger than Number.MAX_SAFE_INTEGER (9007199254740991). Add an n at the end: 9007199254740993n. BigInt and Number cannot be mixed in one operation.
- undefined means a variable has no value yet. null means "no value" on purpose: you set it.
- JavaScript is dynamically typed: a variable has no fixed type, its value does. let x = 5; then x = 'five' is allowed.
- typeof value gives the type as a string. typeof null is 'object', an old bug that will never be fixed. Use Array.isArray(value) to check for an array.
Try it: run the examples, then change the values and see what typeof says.
- string
- number
- number
- bigint
- boolean
- undefined
- object
- symbol
- object
- object
- true
Operators
- Arithmetic: + - * /, % for the remainder (7 % 2 is 1) and ** for the power (2 ** 3 is 8). ++ adds one, -- subtracts one.
- Assignment: = sets a value. += -= *= /= are shortcuts: total += 5 is total = total + 5.
- Comparison: > < >= <= give true or false. === checks the value and the type. == converts the types first, so 5 == '5' is true. Always use === and !==.
- Logical: && (and) is true when both sides are true, || (or) when at least one is, ! (not) flips true and false.
- + with a string joins instead of adding: '5' + 3 is '53'. The other math operators convert to a number: '5' - 3 is 2.
- The ternary operator picks one of two values: const label = age >= 18 ? 'adult' : 'minor'. For more than two outcomes, use if, else if and else.
Try it: guess the output before you press Run. The == and + with strings examples catch out almost everyone the first time.
- 9 5 14 3.5
- 1
- 8
- 6
- 16
- 32
Strings
- A string is text in quotes: 'single', "double" or `backticks`. Pick one style and stick to it.
- Backticks make a template literal: `Hello, ${name}!` puts the value of name into the text. It is easier to read than 'Hello, ' + name + '!'.
- text.length is the number of characters. Characters are numbered from 0: text[0] is the first one, text[text.length - 1] the last.
- text.startsWith('Hi') and text.endsWith('.pdf') return true or false. Both are case-sensitive.
- Other methods you will use all the time: includes, indexOf, slice, toUpperCase, toLowerCase, trim, split and replace.
- A string cannot be changed in place. Every method returns a new string and the original stays the same: text.toUpperCase() does not change text.
Try it: change the text or the search value. Every method runs again, live. Notice that text itself never changes: each method gives back a new value.
| text.length | 31 |
| text.startsWith(search) | false |
| text.endsWith(search) | false |
| text.trim().endsWith('.') | true |
| text.includes(search) | true |
| text.indexOf(search) | 11 |
| text.toUpperCase() | ' LEARNING JAVASCRIPT IS FUN. ' |
| text.toLowerCase() | ' learning javascript is fun. ' |
| text.trim() | 'Learning JavaScript is fun.' |
| text.slice(2, 10) | 'Learning' |
| text[0] | ' ' |
| text.split(' ') | ['', '', 'Learning', 'JavaScript', 'is', 'fun.', '', ''] |
| text.replace(search, 'JS') | ' Learning JSScript is fun. ' |
| `Text: ${text.trim()}` | 'Text: Learning JavaScript is fun.' |
Loops
- A loop runs the same code again and again while a condition is true.
- for (let i = 0; i < 5; i++) { } has three parts: where to start, the condition checked before every round, and what to do after every round.
- while (condition) { } checks the condition first, so the body may never run. do { } while (condition) runs the body once, then checks.
- for (const item of array) gives you each value of an array. for (const key in object) gives you each key of an object.
- break leaves the loop. continue skips the rest of this round and goes to the next.
- If the condition never becomes false, the loop never ends and the tab freezes. Make sure something in the body moves toward the end.
Try it: change the start, the end and the step, and follow the loop one round at a time. The condition is checked before every round. The first time it is false, the loop ends.
for (let i = 0; i < 5; i++) {
console.log(i)
}- i = 00 < 5 is truelogs 0, then i++
- i = 11 < 5 is truelogs 1, then i++
- i = 22 < 5 is truelogs 2, then i++
- i = 33 < 5 is truelogs 3, then i++
- i = 44 < 5 is truelogs 4, then i++
- i = 55 < 5 is falseloop ends
The other loops: run them and change the conditions.
- 3
- 2
- 1
- Go!
Arrays
- An array is an ordered list of values: const subjects = ['HTML', 'CSS', 'JavaScript']. It can hold any type, even a mix.
- Items are numbered from 0. subjects[0] is 'HTML'. subjects.length is 3, so the last item is subjects[subjects.length - 1].
- push adds to the end and pop removes from the end. unshift adds to the start and shift removes from the start.
- includes tells you if a value is in the array. indexOf gives its position, or -1 if it is not there.
- slice(start, end) copies a part and leaves the array alone. splice(start, count) removes items from the array itself.
- join(', ') turns the array into one string. text.split(', ') does the opposite.
- forEach, map and filter run a function for every item. They appear here as a preview and are covered properly in JavaScript (Advanced).
Try it: click a method to call it on subjects. Watch which ones change the array and which only give you an answer.
const subjects = ['HTML', 'CSS', 'JavaScript']Now in code: read, change and loop over arrays.
- red
- blue
- 3
- ['red', 'yellow', 'blue']
- undefined
Objects
- An object groups related values under names: const student = { name: 'Ana', grade: 9 }. Each name: value pair is a property.
- Read a property with a dot, student.name, or with brackets, student['name']. Use brackets when the name is in a variable.
- Assign to change or add a property: student.grade = 10, student.email = 'ana@example.com'. delete student.email removes it. A property that does not exist reads as undefined.
- A function inside an object is a method. Inside a method, this is the object the method was called on.
- for (const key in student) loops over the keys. Object.keys(student) and Object.values(student) give them to you as arrays.
- An array of objects is what most data looks like: a list of students, products or expenses. It is also the shape of the JSON the back-end sends.
Try it: run an example, then add your own properties and log the object again.
- Ana
- 20
- true
- CSS
- undefined
The DOM (Document Object Model)
- When the browser reads your HTML, it builds the DOM: a tree of objects, one for every element, like the tree in the HTML topic. JavaScript changes the page by changing these objects.
- document is the whole page. document.getElementById('title') finds one element by its id. document.querySelector('.note') finds the first match for any CSS selector, and querySelectorAll finds every match.
- textContent reads or sets the text of an element. innerHTML sets HTML, so never give it text the user typed.
- element.style.color = 'red' sets one style. Usually better: element.classList.add('active'), remove and toggle, with the looks kept in your CSS.
- getAttribute and setAttribute read and change attributes like href, src and disabled.
- document.createElement('li') makes a new element, parent.append(child) puts it on the page, and element.remove() takes it off.
- If querySelector returns null, nothing matched. Check the selector, and check that the script runs after the HTML.
Try it: the HTML at the top is a small page. Each example changes it with JavaScript. Press Reset to put the code back, Run to start again from the original page.
<h1 id="title">My shopping list</h1>
<p class="intro">Three things to buy.</p>
<ul id="list">
<li>Bread</li>
<li>Milk</li>
<li class="done">Eggs</li>
</ul>
<p><a id="more" href="https://developer.mozilla.org">Read more</a></p>- <h1 id="title">
- My shopping list
- Bread
- 3 items
- null
Events
- An event is something that happens on the page: a click, a key press, the mouse moving over an element, the page finishing loading. JavaScript can run code when it happens.
- element.addEventListener('click', handler) is the way to do it. The handler is a function. You can add as many listeners as you need.
- The older ways are the onclick="..." attribute in the HTML and the element.onclick = handler property. They work, but the attribute mixes JavaScript into the HTML and the property allows only one handler.
- Common events: click, mouseover and mouseout, input (every change in a text field) and change, keydown, submit on a form, DOMContentLoaded when the HTML is ready, and load when everything, images included, has loaded.
- The handler receives an event object. event.target is the element the event happened on. event.key is the key that was pressed.
- event.preventDefault() stops what the browser would normally do: a form reloading the page, a link opening another page.
Try it: run an example, then click, hover or type on the page. Each event logs to the console as it happens.
<button id="btn">Click me</button>
<p id="out">Not clicked yet.</p>- Nothing logged yet. Look at the page above, or interact with it.
Good habits
- Keep the console open. Most problems are an error message you have not read yet.
- const by default, let when the value changes, never var. Always === instead of ==.
- Give variables names that say what they hold: totalPrice, not tp or x.
- One script file, linked at the end of the body or with defer. No JavaScript inside onclick attributes.
- Change classes, not styles. JavaScript decides the state, CSS decides what that state looks like.
- Write a few lines, run them, check the console, then write the next few.
Practice
- Add an app.js file to your profile page with a defer script tag. Log a message and check it appears in the console.
- Store your name, your age and a list of your skills in variables. Use a template literal to log one sentence about yourself.
- Build the skills list on the page from an array with a loop and createElement, instead of writing the <li> elements by hand.
- Add a dark mode button: a click toggles a dark class on the body, and the colors for it live in your CSS.
- Make the contact form check itself on submit: stop it with preventDefault, check that the email includes @ and the message is not empty, and show an error on the page if not.
- Make a counter: a number on the page with + and - buttons, and a Reset button that only shows once the count is above 0.
Resources
Next up: JavaScript (Advanced): timers, listeners, errors, better form validation, objects and classes, array methods and browser storage.



