FullStack Course LogoFullStack Course
Module: JavaScript
JavaScript·042·10 MIN READ

042: JavaScript: Runtime, Console, Versions, and Script Loading

TOPICS COVERED: JavaScript: Runtime, Console, Versions, and Script Loading

Outcomes

By the end of this lesson, you can:

  • describe JavaScript's role alongside HTML and CSS;
  • run expressions and statements in browser developer tools;
  • load an external classic script or an ES module correctly;
  • use console.log() to observe values;
  • write basic arithmetic and string expressions; and
  • distinguish source code, an evaluated value, and visible console output.

Prerequisites and Retrieval

You should already know that HTML describes the structure of a page and CSS controls its presentation. Before starting, retrieve those ideas by answering these questions:

  1. What does an HTML <script> element do?
  2. What is the difference between text shown in a page and text in its source file?
  3. Predict the mathematical result of 8 + 2 * 3.

No previous programming knowledge is assumed. Use a current browser such as Firefox, Chrome, Edge, or Safari. Open its developer tools and select Console. The console is a place for learning and debugging; it is not the user interface of a finished application.

Terms

  • JavaScript: A cross-platform scripting language that adds behavior and interactivity to web pages. — Source: MDN: JavaScript Guide — Introduction
  • ECMAScript: The standardized language specification (ECMA-262) that JavaScript implements. — Source: ECMA-262
  • host environment: The runtime embedding the engine — browser or server — supplying timers, network, DOM. — Source: MDN: JavaScript execution model
  • engine: The component that parses and executes JavaScript code (V8, SpiderMonkey). — Source: MDN: Glossary — JavaScript
  • console: The developer tool surface where console methods print diagnostics. — Source: MDN: Console API
  • expression: Any valid unit of code that evaluates to (produces) a value. — Source: MDN: Grammar and types
  • statement: An instruction that performs an action; programs are sequences of statements. — Source: MDN: Grammar and types
  • literal: Notation for a fixed value written directly in source: 42, "hi", [1,2]. — Source: MDN: Grammar and types
  • comment: Source annotation ignored by the engine; // single-line, /* */ multi-line. — Source: MDN: Grammar and types
  • classic script: ordinary script code loaded with <script src="..."></script> (course term).
  • module: a script with its own scope and support for import and export, loaded with type="module" (course term).
  • Value (official): "A value is the data that an expression evaluates to." — Source: MDN: Values
  • JavaScript (official): "JavaScript is a lightweight, interpreted, compiled programming language with first-class functions." — Source: MDN: JavaScript Guide — Introduction
  • ECMAScript (official): "ECMAScript is the standardized specification for JavaScript, maintained by Ecma International (ECMA-262)." — Source: ECMAScript Language Specification

Beginner Explanation and Mental Model

It helps to picture a webpage as a small production. HTML provides the cast and scenery, CSS directs the visual presentation, and JavaScript supplies the instructions that react to events and make decisions. JavaScript can calculate totals, respond to clicks, validate input, request data, and update the document. That last point introduces a distinction worth keeping clear: the JavaScript language and browser APIs work together, but they are not the same thing. 2 + 2 is JavaScript. document and the developer console are supplied by the browser's host environment.

The engine reads source code and evaluates it. An expression produces a value: 10 - 3 produces 7, while "web" + "site" produces "website". A statement instructs the program to perform an action. When you call console.log(10 - 3);, the call asks the console to display the value produced by the expression. Developer tools may then show the call's return value as undefined. That separate undefined is not another log message, and it is not an error.

JavaScript is case-sensitive, so console and Console refer to different names. Strings need matching opening and closing quotes. Parentheses group the inputs to a function, and a semicolon makes the end of a statement explicit. JavaScript can insert some semicolons automatically, but this course uses them consistently so that beginner examples are easier to read and reason about.

Comments let you record intent without changing execution:

js
// One-line comment

/* A block comment can
   continue across lines. */

The engine ignores comments, so they do not appear in output. The most useful comments explain why a choice exists or a constraint matters; comments that merely translate an obvious line of code add little value.

Loading code in a page

For a small external classic script whose execution should wait until parsing is complete, this is valid:

html
<script src="app.js" defer></script>

With defer, the browser can continue parsing while it downloads the file. It executes the script after parsing finishes, and deferred scripts retain their order relative to one another. A modern module is loaded like this:

html
<script type="module" src="app.js"></script>

Modules defer execution by default and run in strict mode. Do not add the obsolete and redundant type="text/javascript". An external classic script without async or defer can block parsing while the browser fetches and executes it. async runs the script as soon as it is available and does not guarantee order, so it is the wrong choice when one script depends on another. For the isolated experiments in this lesson, the console is the simplest place to start.

Worked Example: Cafe Receipt

Open the console and enter the lines one at a time rather than pasting the entire program at once. Start with a plain expression:

js
2 + 3

The console displays 5 because the expression you entered evaluates to that value. Now run this complete beginner program:

js
// Prices are written directly as number literals for today's example.
console.log("Cafe receipt");
console.log("Tea:", 40);
console.log("Snack:", 25);
console.log("Subtotal:", 40 + 25);
console.log("Two teas:", 40 * 2);
console.log("Average item price:", (40 + 25) / 2);
console.log("Thank " + "you!");

Expected output:

text
Cafe receipt
Tea: 40
Snack: 25
Subtotal: 65
Two teas: 80
Average item price: 32.5
Thank you!

Trace the program line by line. String literals produce text values, and number literals produce numeric values. With numbers, +, *, and / form arithmetic expressions. The parentheses in the average calculation make the intended grouping explicit. On the final line, + joins two strings. console.log() also accepts multiple arguments, which is why console.log("Tea:", 40) can display the label and number separately instead of requiring you to join them into one string.

To run the same program from a file, create an HTML page that references app.js as a module, place the JavaScript in app.js, and open the HTML page. For this lesson, observe that workflow only; module organization comes later.

Intermediate Example: Predict, Then Observe

Expressions can be nested, and their operators follow specific rules. Predict each result before running the code, then compare your predictions with the console:

js
console.log("Order calculations");
console.log(12 + 6 * 2);
console.log((12 + 6) * 2);
console.log(17 % 5);
console.log(2 ** 4);
console.log("Room " + 3);
console.log(9 > 4);
console.log(10 === 10);

Expected output:

text
Order calculations
24
36
2
16
Room 3
true
true

Multiplication has higher precedence than addition, which makes 12 + 6 * 2 equal to 24. Parentheses change that order, so (12 + 6) * 2 is 36. % returns a remainder, and ** performs exponentiation. 9 > 4 and strict equality, 10 === 10, evaluate to Boolean values. Comparisons are studied in depth in 046, while coercion and equality edge cases are handled in 045. For now, the useful observation is simply that expressions can produce values other than numbers and strings.

Optional Advanced Extension: Script Loading Timeline

Create three tiny external files, each logging its filename. Compare normal, defer, async, and module script elements while watching both the Console and Network panels. Use this model when you interpret what you observe:

  • classic without async or defer: fetch and execute while parsing is blocked;
  • classic with defer: fetch alongside parsing, execute after parsing in document order;
  • classic with async: fetch alongside parsing, execute when ready, with no dependency order;
  • module without async: fetch the module graph alongside parsing, execute after parsing.

These are browser loading rules, not a promise that network requests finish in source order. Do not use document.write() or timers to simulate dependencies.

Deep Dive: ECMAScript, Engines, and Execution Environments

JavaScript is the language. ECMAScript is the standardized specification that defines its core behavior. Browsers and other runtimes implement that specification through engines such as V8, SpiderMonkey, and JavaScriptCore. A browser then contributes Web APIs including the DOM, fetch, timers, storage, and events. Node.js provides a different host environment.

This boundary matters in practice. Code can be valid JavaScript and still depend on an API that does not exist in every runtime. Try these checks in a browser and, where available, in Node.js:

js
console.log(typeof Array);      // "function" in browser and Node.js
console.log(typeof document);   // "object" in a browser, usually "undefined" in Node.js
console.log(typeof process);    // usually "undefined" in a browser, "object" in Node.js

JavaScript versions without memorizing every year

You do not need to memorize every ECMAScript edition. You do need a rough sense of how the language has evolved:

  • ES5 standardized many foundations still used today.
  • ES2015 (ES6) introduced let, const, classes, modules, arrow functions, promises, destructuring, and more.
  • Modern JavaScript evolves yearly, with smaller additions instead of rare giant releases.
  • Browser support and build tooling determine whether a feature is safe for your target users.

When you encounter unfamiliar syntax or an API, verify its support instead of assuming that "modern" means "available everywhere."

Classic scripts versus modules

html
<script src="legacy.js"></script>
<script type="module" src="app.js"></script>

Modules are deferred automatically, have their own module scope, support import and export, and run in strict mode. Classic scripts behave differently and may create globals more easily. Those differences affect how files see one another and when their code runs.

Execution context thought experiment

For each snippet, predict what the runtime must provide before it can work:

js
const tax = 0.18;
console.log(100 + 100 * tax);

This uses core JavaScript and is portable.

js
document.querySelector("#total").textContent = "₹118";

This requires a browser DOM.

js
await fetch("/api/orders");

fetch is a host API. It is widely available in modern browsers and modern Node.js, but it is not part of the ECMAScript language specification itself.

The habit to build is straightforward: separate language behavior from host-environment behavior. When something fails, first ask whether the problem is in JavaScript itself or in the runtime APIs around it.

Mistakes and Debugging

  • ReferenceError: Console is not defined: use lowercase console.
  • SyntaxError near a string: check that the opening and closing quotes match.
  • Unexpected concatenation: "5" + 2 is "52", because one operand is text. Do not rely on coercion; keep numeric data numeric.
  • Only undefined appears: the result of a log call may be displayed separately. Look for the logged line immediately above it.
  • Nothing appears from a file: verify the src path, open the Network panel, and check the Console for a syntax or loading error.
  • Code runs before expected HTML exists: use a module or a deferred classic script rather than relying on a fragile script position.
  • Old console declarations collide: refreshing the page creates a fresh environment. If you re-enter the same declaration without refreshing, some consoles can report an error.

Debug in small steps. Start with the first error, including its file and line number. Reduce a failing expression to simpler pieces and log each piece separately. Never use eval() to run text as code: it introduces security and maintainability problems and is unnecessary here.

Best Practices

  • Use the browser console for experiments and temporary diagnostics, not permanent user-facing messages.
  • Prefer an external type="module" script for new browser projects; use defer for ordered classic scripts when modules are not suitable.
  • Write one clear statement per line and use consistent semicolons.
  • Use meaningful whitespace and parentheses when they clarify an expression.
  • Keep data and labels separate in logs: console.log("Total:", 65); is easy to inspect.
  • Do not log passwords, tokens, or personal information.
  • Write comments about intent or constraints, and remove stale comments.
  • Treat errors as precise evidence: inspect the type, message, file, and line.

Tiered Exercises

Run the JavaScript snippets in the browser console or as a classic script. For a file, save it as app.js and load it with <script src="app.js" defer></script>.

Core

  1. In the console, calculate the sum, difference, product, division result, and remainder of 18 and 5.
  2. Log the exact text JavaScript starts here.
  3. Add a one-line comment that does not appear in output.

Practice

Write console statements for a cinema booking with three tickets costing 120 each and a booking fee of 30. Display a heading, ticket cost, fee, and final total. Use parentheses where they improve clarity.

Professional Extension

Predict and then check the outputs of 5 + 2 * 4, (5 + 2) * 4, 20 % 6, and "Day " + 31. Explain why each result has its value.

Complete Solutions

js
// Arithmetic practice
console.log(18 + 5); // 23
console.log(18 - 5); // 13
console.log(18 * 5); // 90
console.log(18 / 5); // 3.6
console.log(18 % 5); // 3
console.log("JavaScript starts here");

The comment is ignored. Every expression passed to console.log() is evaluated before its result is displayed.

js
console.log("Cinema booking");
console.log("Tickets:", 3 * 120);
console.log("Booking fee:", 30);
console.log("Total:", (3 * 120) + 30);

Expected output:

text
Cinema booking
Tickets: 360
Booking fee: 30
Total: 390
js
console.log(5 + 2 * 4);   // 13: multiplication first
console.log((5 + 2) * 4); // 28: grouped addition first
console.log(20 % 6);      // 2: remainder after division
console.log("Day " + 31); // 031: string concatenation

Recap and Exit Questions

JavaScript supplies page behavior and general-purpose logic. Its engine evaluates expressions into values and executes statements, while the console makes those steps observable. Scripts may be classic scripts or modules, and that loading choice affects when code executes.

  1. What is the difference between an expression and a statement?
  2. What does console.log() help a developer do?
  3. Why do (2 + 3) * 4 and 2 + 3 * 4 differ?
  4. When should a classic external script use defer?
  5. What is one step you would take when a script produces no output?

Official References

References checked 2026-08-24.

Reader page: /javascript/lesson/042/javascript-runtime-console-versions-and-script-loading