PLAINFINCH learn by building

How JavaScript works

You will connect a script to a page and write a first program that finds an element and changes its text.

What does JavaScript add to a page?

A web page has three layers. HTML says what is on the page: a heading, a paragraph, a button. CSS says how it looks: colours, spacing, layout. JavaScript says what happens: what changes when someone clicks, types, scrolls, or when data arrives from a server. People often call these structure, style and behaviour.

Without JavaScript a page still works. Links go to other pages, forms send their data, and text is readable. JavaScript adds the parts that respond without a full page reload: a basket total that updates as you add loaves, a menu that opens and closes, a search box that filters a list while you type.

The browser has a JavaScript engine built in. Chrome and Edge use V8, Firefox uses SpiderMonkey, Safari uses JavaScriptCore. They all follow the same standard, called ECMAScript, which gets a new edition every year. Everything here works in every current browser.

// HTML: <p class="status">Loading...</p>
const status = document.querySelector('.status');
status.textContent = 'Open today until 4pm';
FigureThe browser reads the HTML from top to bottom, builds the page, then reaches the script tag at the end of body and runs it line by line, changing the page.The browser reads the HTML from top to bottom, builds the page, then reaches the script tag at the end of body and runs it line by line, changing the page.
The browser builds the page from the HTML first. When it reaches the script at the end of <body>, every element above already exists, so the script can find them and change their text.

Where does the script tag go?

You connect a JavaScript file to a page with a <script> element whose src attribute points at the file. The position of that element changes the result, because the browser reads HTML from top to bottom and stops to run a plain script the moment it reaches it.

If the script sits in the <head>, it runs before the browser has read the <body>. Any line that looks for a heading or a button finds nothing, because those elements do not exist yet. That is the most common reason a beginner's first script fails with an error about null.

There are two good fixes. The traditional one is to put the <script> tag as the last thing inside <body>. By then every element above it exists. The modern one is to keep the tag in the <head> and add the defer attribute. A deferred script downloads while the page is being read and runs once the whole HTML document has been parsed, in the order the scripts appear.

Use defer in the <head> for new projects. It starts the download earlier, keeps all your setup in one place, and behaves the same as a script at the end of the body. Scripts with type="module" are deferred automatically. The PlainFinch editor runs script.js after the page is built, so you can find any element in index.html.

<head>
  <title>Rye & Crumb</title>
  <script src="script.js" defer></script>
</head>

In what order does the browser run your code?

A script runs from the first line to the last, one statement at a time. Line 3 cannot use something that line 7 creates, because line 7 has not happened yet. Later you will meet functions and events, which let code wait and run later, but the file itself is always read in order.

Each script also runs to the end before the browser does anything else on that page. While your script runs, the page cannot repaint and clicks are not handled. For short scripts that is invisible. It becomes important only when something takes a long time, which is why the editor stops endless loops after 1.5 seconds.

If one line throws an error, the script stops there. Lines above it have already done their work, lines below it never run. When the page looks half finished, the error message in the Console tells you exactly where it stopped.

What is a statement, and do you need semicolons?

A statement is one instruction: create this variable, change that text, log this value. Most statements fit on one line and end with a semicolon, the way a sentence ends with a full stop.

JavaScript has a feature called automatic semicolon insertion, which adds missing semicolons in most places where a line obviously ends. It works most of the time and fails in a few confusing cases, such as a line that starts with ( or [. PlainFinch code always writes the semicolons, which is what most style guides and code formatters do. You will see code online without them; both styles run.

Whitespace and line breaks mostly do not matter to the engine. Indentation is for people. Use two spaces per level, as every example here does, so the shape of the code matches its meaning.

const shop = 'Rye & Crumb';
const opens = '8am';
console.log(shop, 'opens at', opens);

How do comments work?

A comment is text the engine ignores. Two slashes // start a comment that runs to the end of the line. /* and */ wrap a comment that can cover several lines.

Good comments say why, because the code already says what. A comment like // set the text above a line that sets the text adds nothing. A comment like // The bakery closes early on Sundays explains a decision a reader could not guess.

Comments are also a quick way to switch a line off while you test something. Put // in front, run the code, and remove it again afterwards. Do not leave large blocks of dead, commented code in a finished file.

/* Opening hours come from the shop owner,
   not from the server. */
const hours = '8am to 4pm';
// const hours = '9am to 5pm'; (winter hours)

How do you run and watch code in the editor?

The editor has three files: index.html, style.css and script.js. You mostly edit script.js. Every change reruns the page from scratch, with the HTML built first and then your script run on top of it.

The Console panel under the page shows everything your code logs with console.log, and it explains errors in plain words with the line number. Keep an eye on it from the start. A silent page with a red line in the Console is the most common sign that a script stopped early.

The Step lens runs the script one line at a time. After each step it shows every variable and its current value. Use it on the demo: step past the querySelector lines and you can see heading and status holding the two elements. The Changes lens outlines any element your script changed, so you can see the paragraph light up when its text is replaced.

What does a first real program look like?

A useful first program finds an element and changes it. That is the core of most front-end JavaScript: find something on the page, then change its text, its classes or its attributes.

document is an object the browser gives you that represents the whole page. document.querySelector() takes a CSS selector, the same kind you write in a stylesheet, and returns the first matching element. If nothing matches, it returns null.

Once you have the element in a variable, setting its textContent replaces all the text inside it. The HTML file on disk does not change. You changed the live copy of the page that the browser keeps in memory, which is called the DOM. Reload, and the script runs again from the original HTML.

const heading = document.querySelector('#greeting');
heading.textContent = 'Rye Day at Rye & Crumb';
console.log('Heading updated');

What should you check in AI-generated JavaScript?

AI tools often hand you a script plus a sentence like "add this to your page". Check where the script tag goes. A script in the <head> without defer that looks up elements will fail with a null error. Moving the tag or adding defer fixes it.

Look for var declarations and onclick="..." attributes in the HTML. Both still work, but they come from older tutorials. Modern code uses const and let and attaches behaviour with addEventListener, which later lessons cover.

Watch for innerHTML used to set plain text. It works, but it reads the string as HTML, which is slower and can be a security problem when the text comes from a user. textContent is the right choice for text.

Field notes

  • HTML holds the content, CSS sets the look, and JavaScript adds behaviour.
  • The browser runs your script from the first line to the last, in order.
  • Where you place the script tag decides whether the HTML exists when it runs.
  • Most front-end code finds an element on the page and then changes it.

Easy to get wrong

Without defer, the script runs before the body exists, so every querySelector returns null and the first line that uses the result throws an error.

Property names are case sensitive. The lowercase version raises no error; it creates a new property the browser ignores, so the page silently stays the same.

The selector follows CSS rules. Without the dot it looks for a <status> element, which does not exist, and returns null.

Questions people ask

Is JavaScript the same as Java?

No. The names are similar for marketing reasons from 1995. They are different languages with different rules and uses.

Can I write JavaScript inside the HTML file?

Yes, between <script> and </script> tags. A separate file is easier to edit, cache and reuse, so most projects keep scripts in .js files.

What is the difference between `defer` and `async`?

Both download without blocking the page. A defer script waits until the HTML is parsed and runs in order. An async script runs as soon as it arrives, in any order, which suits independent scripts like analytics.

Does changing the page with JavaScript change my HTML file?

No. The script changes the page in the browser's memory. Reload and you start again from the HTML file.

Keep going