Unit 3 · 20 min read
Scripting Language (JavaScript)
What the syllabus asks for 9
- Embedding JavaScript
- Variables, data types, operators
- Control flow
- Functions
- Arrays, objects, strings, Math, Date, JSON
- Regular expressions
- The DOM and events
- Timers, errors and asynchronous code
- Seeing JavaScript: people, scope, events and the loop
JavaScript is the programming language of the browser: it reads and changes the page (the DOM), reacts to events and talks to servers. It also runs outside browsers (Node.js).
The js examples in this unit were run with Node.js and their output is real; examples that touch the page are given as HTML.
- Embedding scripts; variables, types, operators, control flow.
- Functions, arrays, objects, strings, Math, Date, JSON.
- The DOM, events and form validation (with regular expressions).
- Timers and error handling.
3.1 Embedding JavaScript
<script>alert("inline script");</script> <!-- in the page -->
<script src="app.js" defer></script> <!-- external file (preferred); defer runs it after parsing -->
<button onclick="alert('Hi')">Click</button> <!-- inline handler: avoid in real projects -->
External files are cached and keep HTML clean. Output techniques: console.log() (developer console), alert(), document.write() (avoid), and changing the DOM (element.textContent).
JavaScript is case-sensitive, dynamically typed, and ; ends statements (optional but recommended).
3.2 Variables, data types, operators
let (block-scoped, reassignable), const (block-scoped, cannot be re-assigned), var (function-scoped, old; avoid).
Types: number, string, boolean, undefined, null, bigint, symbol and object (arrays and functions are objects). typeof x reports the type.
Operators: arithmetic + - * / % **, comparison < > <= >=, === (strict, no type conversion) versus == (loose), logical && || !, assignment += -=, ternary c ? a : b.
let a = 7, b = 2;
console.log(a + b, a - b, a * b, a / b, a % b, a ** b);
console.log("5" + 3, "5" - 3, "5" * "2");
console.log(0 == "0", 0 === "0", null == undefined, null === undefined);
console.log(typeof 42, typeof "hi", typeof true, typeof undefined, typeof null, typeof [], typeof (() => 1));
console.log(0.1 + 0.2, (0.1 + 0.2).toFixed(2), Number("12px"), parseInt("12px"), parseFloat("3.14abc"));
const age = 20;
console.log(age >= 18 ? "adult" : "minor");
9 5 14 3.5 1 49
53 2 10
true false true false
number string boolean undefined object object function
0.30000000000000004 0.30 NaN 12 3.14
adult
Notice "5" + 3 is string concatenation ("53") while "5" - 3 converts to number; 0.1 + 0.2 is not exactly 0.3 (binary floating point); typeof null is "object", a historical quirk. Falsy values: false, 0, "", null, undefined, NaN.
3.3 Control flow
for (let i = 1; i <= 5; i++) {
if (i % 2 === 0) continue;
console.log("odd", i);
}
let n = 0;
while (n < 3) n++;
do { n--; } while (n > 0);
const day = 3;
switch (day) {
case 1: console.log("Sun"); break;
case 3: console.log("Tue"); break;
default: console.log("other");
}
for (const ch of "web") console.log(ch);
for (const key in { x: 1, y: 2 }) console.log(key);
odd 1
odd 3
odd 5
Tue
w
e
b
x
y
for…of iterates values of arrays and strings; for…in iterates the keys of an object. break leaves a loop, continue skips to the next iteration.
3.4 Functions
function area(w, h = 1) { return w * h; } // declaration, default parameter
const square = x => x * x; // arrow function
const counter = (() => { let c = 0; return () => ++c; })(); // closure keeps c alive
console.log(area(3, 4), area(5), square(9));
console.log(counter(), counter(), counter());
function sum(...nums) { return nums.reduce((s, x) => s + x, 0); }
console.log(sum(1, 2, 3, 4));
console.log([3, 1, 2].map(square), [1, 2, 3, 4].filter(x => x % 2 === 0));
12 5 81
1 2 3
10
[ 9, 1, 4 ] [ 2, 4 ]
Functions are first-class: they can be stored in variables, passed to other functions (callbacks) and returned. A closure is a function that remembers the variables of the scope where it was created.
Hoisting: function declarations are available before their line; let/const are not.
3.5 Arrays, objects, strings, Math, Date, JSON
const marks = [85, 72, 91];
marks.push(64); marks.unshift(50);
console.log(marks, marks.length, marks.indexOf(91), marks.includes(72));
console.log(marks.slice(1, 3), marks.sort((a, b) => b - a), marks.join(" | "));
const student = { name: "Sita", age: 20, address: { city: "Kathmandu" }, greet() { return "Hi " + this.name; } };
student.email = "sita@example.np";
console.log(student.name, student["age"], student.address.city, student.greet(), Object.keys(student));
const s = " Web Technology ";
console.log(s.trim().toUpperCase(), s.length, s.trim().split(" "), s.includes("Tech"), s.trim().slice(0, 3), s.replace("Web", "Internet"));
console.log(Math.max(4, 9, 2), Math.round(2.5), Math.floor(-1.5), Math.sqrt(144), Math.PI.toFixed(4));
const d = new Date(2082, 0, 15);
console.log(d.getFullYear(), d.getMonth(), d.getDate(), d.getDay());
const json = JSON.stringify({ id: 1, tags: ["a", "b"], ok: true });
console.log(json, JSON.parse(json).tags[1]);
[ 50, 85, 72, 91, 64 ] 5 3 true
[ 85, 72 ] [ 91, 85, 72, 64, 50 ] 91 | 85 | 72 | 64 | 50
Sita 20 Kathmandu Hi Sita [ 'name', 'age', 'address', 'greet', 'email' ]
WEB TECHNOLOGY 18 [ 'Web', 'Technology' ] true Web Internet Technology
9 3 -2 12 3.1416
2082 0 15 4
{"id":1,"tags":["a","b"],"ok":true} b
JSON (JavaScript Object Notation) is the standard text format for data exchange: keys in double quotes; values are strings, numbers, booleans, null, arrays, objects. JSON.stringify makes text from an object and JSON.parse does the reverse.
Arrays have map, filter, reduce, forEach, find, some, every, splice, concat.
3.6 Regular expressions
A regular expression describes a text pattern: /^[A-Za-z]+$/ (letters only), \d digit, \w word character, . any, + one or more, * zero or more, {n,m} counts, ^ and $ anchor start and end.
const email = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const phone = /^9[78]\d{8}$/; // Nepali mobile: 97xxxxxxxx or 98xxxxxxxx
const strong = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/;
for (const t of ["sita@example.np", "bad@", "x y@z.com"]) console.log(t, email.test(t));
for (const t of ["9841234567", "9611111111", "984123"]) console.log(t, phone.test(t));
console.log(strong.test("Passw0rdOK"), strong.test("password"));
console.log("a1b22c333".match(/\d+/g), "2082-04-12".replace(/(\d+)-(\d+)-(\d+)/, "$3/$2/$1"));
sita@example.np true
bad@ false
x y@z.com false
9841234567 true
9611111111 false
984123 false
true false
[ '1', '22', '333' ] 12/04/2082
3.7 The DOM and events
The Document Object Model is the browser's tree of the page that JavaScript can read and modify.
| Task | Code |
|---|---|
| Find an element | document.getElementById("id"), document.querySelector(".cls"), querySelectorAll("li") |
| Read/change text | el.textContent = "Hi"; el.innerHTML (careful: can inject scripts) |
| Change attributes/style | el.setAttribute("href", "…"), el.style.color = "red", el.classList.add("on") |
| Create/insert/remove | document.createElement("li"), parent.appendChild(li), el.remove() |
| Listen to events | el.addEventListener("click", handler) |
Common events: click, dblclick, mouseover, keydown, input, change, submit, focus, blur, load, DOMContentLoaded. The handler receives an event object (e.target, e.preventDefault()).
Events bubble from the target up through its ancestors, so one listener on a parent can handle all children (event delegation).
<ul id="todo"></ul>
<input id="item" placeholder="New task"> <button id="add">Add</button>
<script>
const list = document.getElementById("todo");
document.getElementById("add").addEventListener("click", () => {
const box = document.getElementById("item");
if (box.value.trim() === "") return;
const li = document.createElement("li");
li.textContent = box.value.trim();
list.appendChild(li);
box.value = "";
});
list.addEventListener("click", e => { if (e.target.tagName === "LI") e.target.remove(); }); // delegation
</script>
Form validation
<form id="reg" novalidate>
<input id="email" name="email" placeholder="Email"> <span id="emsg" style="color:red"></span>
<input id="pass" type="password" placeholder="Password (8+, upper, lower, digit)">
<button>Register</button>
</form>
<script>
document.getElementById("reg").addEventListener("submit", e => {
const ok = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(document.getElementById("email").value);
document.getElementById("emsg").textContent = ok ? "" : "Enter a valid email";
if (!ok) e.preventDefault(); // stop submission
});
</script>
3.8 Timers, errors and asynchronous code
function risky(x) { if (x < 0) throw new Error("negative not allowed"); return Math.sqrt(x); }
try { console.log(risky(16)); console.log(risky(-4)); }
catch (err) { console.log("caught:", err.message); }
finally { console.log("done"); }
setTimeout(() => console.log("after 10 ms"), 10);
console.log("this prints first");
const wait = ms => new Promise(res => setTimeout(() => res("waited " + ms), ms));
(async () => { console.log(await wait(20)); })();
4
caught: negative not allowed
done
this prints first
after 10 ms
waited 20
setTimeout(fn, ms) runs once, setInterval(fn, ms) repeatedly (stop with clearInterval).
JavaScript is single-threaded; slow work (network) is handed off and its callback or Promise continues later, which is why "this prints first" appears before "after 10 ms". async/await write promise code in a straight line.
AJAX with fetch("/api").then(r => r.json()) loads data without reloading the page (Unit 6).
3.9 Seeing JavaScript: people, scope, events and the loop
JavaScript is a small language with a few ideas that surprise beginners: scope, type coercion, event flow and the single-threaded event loop.
The plate shows the two people most linked to the language and its data format; the figures draw the ideas and the code blocks next to them were run in Node.js 22 so that every printed value is real.


console.log("A");
setTimeout(() => console.log("B"), 0);
Promise.resolve().then(() => console.log("C"));
console.log("D");
A
D
C
B
console.log("5" + 3, "5" - 3, 0 == "", NaN === NaN, typeof null, 0.1 + 0.2);
53 2 true false object 0.30000000000000004
const total = [1, 2, 3, 4, 5, 6].filter(n => n % 2 === 0).map(n => n * n).reduce((a, b) => a + b, 0);
console.log(total);
56
3.9.1 Eight uses of JavaScript in a web page
- Form validation. JavaScript checks a field before the form is sent and shows a message at once. For example, a scholarship form can test a Nepali mobile number with the pattern in Figure 3.6 and warn the student immediately. This saves a trip to the server, although the server must repeat the check for safety.
- Changing the page without reloading. Scripts change text, add rows and show or hide sections using the DOM. A live notice board can add a new notice at the top as soon as it is published. The user sees the update without losing the place on the page.
- Reacting to the user. Clicks, key presses, scrolling and touches are events that call functions. A menu opens when the hamburger icon is tapped, and a search box can suggest names as the user types. Good event handling makes a page feel fast and alive.
- Talking to servers (AJAX and fetch). The fetch function requests JSON in the background and updates part of the page. The NEPSE market widget on a news site loads fresh prices every few seconds this way. Only a few bytes travel, which matters for users on limited mobile data.
- Interactive widgets. Image sliders, tabs, calendars, date pickers and accordions are built with scripts. A Nepali date converter between Bikram Sambat and the English calendar is a typical example. These widgets turn static pages into small applications.
- Storing data in the browser. localStorage and sessionStorage keep small values such as a theme choice or a half-written form. A quiz page can save the answers so that a refresh does not lose them. Sensitive data such as passwords should never be stored there.
- Drawing, animation and media. With canvas, SVG and the animation functions, scripts draw charts, games and maps. A results page can show a bar chart of pass percentage by faculty. Media players use JavaScript for play, pause and volume controls.
- Running on the server and in apps. With Node.js the same language builds servers, tools and APIs, and frameworks build mobile and desktop apps. A small college can therefore use one language from the browser to the database. This is one reason JavaScript is among the most widely used languages.
Formula and fact sheet
let/constblock scope;===strict equality; falsy: false, 0, "", null, undefined, NaN.- Functions are first-class; closures remember scope; arrow
x => x * x. - JSON:
stringify/parse. Array methods: map, filter, reduce, forEach. - DOM:
querySelector,textContent,addEventListener,createElement, events bubble. - Validate with regular expressions in the browser and on the server.
Chapter summary
- JavaScript adds behaviour: variables and types, control flow, functions and closures, arrays, objects and JSON.
- The DOM and events let scripts read and change the page; forms are validated before submission.
- Errors use try/catch/finally; timers and promises handle work that finishes later.
Practice
- Differentiate
let,constandvar;==and===. - Write a function that returns the largest of an array without
Math.max. - Predict the output:
console.log("3" + 4, "3" * "4", [] + [], typeof NaN). - Write a regex for a six-digit PIN and test it.
- Write the DOM code to change a paragraph's colour to blue when a button is clicked.
- What is a closure? Give an example.
- Explain event bubbling and delegation.
- Why does
setTimeout(f, 0)run after the code that follows it?
Answers and worked solutions
1. let: block-scoped, reassignable; const: block-scoped, binding cannot be reassigned; var: function-scoped, hoisted. == converts types (0 == "0" true); === compares type and value (false).
2. function max(a){ let m = a[0]; for (const x of a) if (x > m) m = x; return m; }
3. "34" 12 "" "number" (string concatenation, numeric multiplication, two empty arrays converting to empty strings, typeof NaN is "number").
4. /^\d{6}$/.test("123456") is true; "12345" false.
5. document.getElementById("btn").addEventListener("click", () => { document.getElementById("p").style.color = "blue"; });
6. A function plus the variables of its defining scope: const c = (() => { let n = 0; return () => ++n; })(); each call to c() increases the private n.
7. An event on an element propagates upward to its ancestors; a single listener on a parent can inspect e.target and handle events from many children, including ones added later.
8. The callback is queued and only runs when the current synchronous code has finished.
Model answers: medium (5 marks) and long (10 marks) questions
Q1 (5 marks). Differentiate var, let and const. Explain scope and hoisting with an example.
Introduction. ES2015 added let and const to fix problems of var; the three differ in scope, hoisting and re-assignment (section 3.2, Figure 3.2).
- var is function-scoped, hoisted to the top of its function and initialised to undefined, can be re-declared and re-assigned. It ignores block braces, so a var declared in an if block is visible after it.
- let is block-scoped, can be re-assigned but not re-declared in the same scope. It is hoisted but stays in the temporal dead zone until its line runs, so early use throws ReferenceError.
- const is block-scoped like let, must be given a value when declared and cannot be re-assigned. The object it holds can still change: const list = []; list.push(1) is allowed.
- Scope chain. Inner functions see variables of outer functions; the engine looks outwards, never inwards. In Figure 3.2, g sees z, y and x and f() returns 6.
- Good practice. Use const by default, let when the value must change, and avoid var.
console.log(typeof undeclared, (function () { try { return tdz; let tdz = 1; } catch (e) { return e.name; } })());
undefined ReferenceError
| Feature | var | let | const |
|---|---|---|---|
| Scope | Function | Block | Block |
| Re-declare | Yes | No | No |
| Re-assign | Yes | Yes | No |
| Before its line | undefined | ReferenceError | ReferenceError |
Conclusion. Block scope with let and const makes code more predictable than var, so modern code prefers them.
Q2 (5 marks). Explain event handling and event bubbling in JavaScript with an example. How does event delegation use it?
Introduction. An event is a signal that something happened, such as a click; a handler is a function that runs in response (section 3.7, Figure 3.4).
- Registering. Use element.addEventListener("click", handler). It allows many handlers for one event, unlike the old onclick property, which holds only one.
- The event object. The handler receives an object with type, target (where it happened), currentTarget and methods preventDefault and stopPropagation.
- Flow. The event first travels down the tree (capture), reaches the target, and then bubbles up through every ancestor. Most events bubble; focus does not.
- Delegation. Instead of attaching a listener to every row of a table, attach one to the table and read event.target. It uses less memory and also works for rows added later.
- Control. preventDefault stops the browser action (form submit, link follow); stopPropagation stops the bubbling.
<ul id="menu"><li data-id="1">Notices</li><li data-id="2">Results</li></ul>
<script>
document.getElementById("menu").addEventListener("click", function (e) {
if (e.target.tagName === "LI") alert("Open item " + e.target.dataset.id);
});
</script>
Conclusion. Because events bubble, one listener on a parent can handle all its children, which is the foundation of efficient delegation.
Q3 (10 marks). Write a JavaScript program to validate a registration form (name not empty, valid Nepali mobile number, password of at least 8 characters) and explain the DOM, event and regular-expression concepts used.
Introduction. Client-side validation gives instant feedback and reduces server traffic.
It uses three ideas of this unit: the DOM to read and change the page, events to run code at the right time, and regular expressions to test patterns.
The server must still validate again because JavaScript can be switched off or altered (sections 3.6 and 3.7, Figures 3.4 and 3.6).
- Selecting elements. document.getElementById or querySelector returns the node of the input, the error paragraph or the form.
- Reading values. input.value is a string; trim() removes spaces at the ends so that a name of only spaces is rejected.
- Listening for submit. form.addEventListener("submit", fn) runs fn when the form is sent. Inside it, event.preventDefault() stops submission if any rule fails.
- Regular expression.
/^9[78]\d{8}$/accepts exactly ten digits beginning 97 or 98; test() returns true or false (Figure 3.6). - Showing errors. Collect messages in an array and write them with textContent into the error element; textContent is safer than innerHTML because it does not run markup.
- Accessibility. Set aria-live="polite" on the error area so screen readers announce the message.
- Clearing. Reset the message at the start of each attempt so old errors do not remain.
- Server check. After the client check passes the form is sent, and the server validates again.
<form id="reg"><input id="nm"><input id="ph"><input id="pw" type="password">
<button>Register</button><p id="err" aria-live="polite"></p></form>
<script>
const form = document.getElementById("reg");
form.addEventListener("submit", function (e) {
const errors = [];
if (document.getElementById("nm").value.trim() === "") errors.push("Name is required.");
if (!/^9[78]\d{8}$/.test(document.getElementById("ph").value)) errors.push("Enter a 10-digit mobile number starting 97 or 98.");
if (document.getElementById("pw").value.length < 8) errors.push("Password needs at least 8 characters.");
document.getElementById("err").textContent = errors.join(" ");
if (errors.length > 0) e.preventDefault();
});
</script>
| Concept | Where used | Purpose |
|---|---|---|
| DOM | getElementById, textContent | Read and change the page |
| Event | submit listener | Run code when the form is sent |
| Regex | test() | Check the phone pattern |
| preventDefault | inside the handler | Block an invalid submission |
Conclusion. The program reads values from the DOM, tests them when the submit event fires, shows all errors together and blocks submission if any exist. It improves the user experience but is never a replacement for server-side validation.