Unit 4: JavaScript Fundamentals
I. Introduction to JavaScript
JavaScript was written by Brendan Eich at Netscape in May 1995 (prototyped in ten days, shipped as "LiveScript", renamed for marketing reasons) to add behaviour to static HTML pages. It was standardised as ECMAScript by Ecma International (ECMA-262, 1st edition, June 1997); the modern language dates from ES6 / ES2015 (June 2015), which introduced let, const, arrow functions, classes and template literals, after which releases became annual (ES2016, ES2017, …).
Defining characteristics assumed by every later section:
- Interpreted and JIT-compiled: source is executed by an engine (V8 in Chrome/Node.js, SpiderMonkey in Firefox) with no separate compile step; syntax errors surface only when the script is parsed.
- Dynamically typed: a variable has no declared type; the value carries the type, so
let x = 5; x = "five";is legal. - Weakly typed: the engine coerces types automatically, so
"5" * 2yields the number10. - Multi-paradigm: supports imperative, functional (functions are first-class values) and prototype-based object-oriented styles.
- Single-threaded and event-driven: one call stack plus an event loop; long computations block the page.
- Host-embedded: the language core (ECMAScript) has no I/O. Browsers add the DOM and
window; Node.js addsfsandrequire. - Placement in a page:
<script src="app.js" defer></script>before</head>, or a<script>block before</body>, so the DOM exists before the code runs. - Strict mode:
"use strict";at the top of a file or function bans undeclared variables and silent errors; ES modules are strict automatically.
II. Bindings and Types — how values are named and classified
A binding associates an identifier with a value in memory; a type determines the operations legal on that value.
A. Variables and Constants
A variable is a named, re-assignable binding; a constant is a binding that cannot be re-assigned after initialisation.
var(pre-ES6): function-scoped, hoisted and initialised toundefined, re-declarable.console.log(a); var a = 1;printsundefinedrather than throwing.let: block-scoped, re-assignable, not re-declarable in the same block; in the temporal dead zone from block entry until its declaration, so early access throwsReferenceError.const: block-scoped and must be initialised at declaration (const PI = 3.14159;). Re-assignment throwsTypeError: Assignment to constant variable.- Constant binding ≠ immutable value:
const arr = [1,2]; arr.push(3);is legal — only the reference is frozen.Object.freeze(obj)freezes contents.
- Constant binding ≠ immutable value:
- Naming rules: must begin with a letter,
_or$; case-sensitive (total ≠ Total); reserved words such asclassandreturnare forbidden. Convention:camelCasefor variables,UPPER_SNAKE_CASEfor fixed constants. - Practice: default to
const, useletonly when re-assignment is needed, avoidvar.
B. Data Types
JavaScript has seven primitive types plus objects; primitives are immutable and copied by value, objects are copied by reference.
| Type | Example | typeof result |
|---|---|---|
| number | 42, 3.14 |
"number" |
| string | "hi" |
"string" |
| boolean | true |
"boolean" |
| undefined | declared, unassigned | "undefined" |
| null | intentional empty value | "object" (historic bug) |
| symbol (ES6) | Symbol("id") |
"symbol" |
| bigint (ES2020) | 9007199254740993n |
"bigint" |
| object / array / function | {}, [], f(){} |
"object" / "object" / "function" |
- Value vs reference:
let a = {n:1}; let b = a; b.n = 2;leavesa.n === 2, whereas the same with numbers leaves the original unchanged. - Detecting arrays:
typeof []gives"object", so useArray.isArray([])→true. nullvsundefined:undefinedis the engine's "no value assigned";nullis the programmer's deliberate "empty".
C. Numbers and Boolean Values
All ordinary numbers are IEEE 754 64-bit doubles — there is no separate integer type.
- Precision limit: 53 bits of mantissa, so
Number.MAX_SAFE_INTEGER === 9007199254740991(2⁵³−1) and0.1 + 0.2 === 0.30000000000000004. Compare with a tolerance:Math.abs(x - y) < 1e-9. - Special values:
Infinity(1/0),-Infinity, andNaNfrom invalid arithmetic ("abc" * 2).NaN !== NaN; test withNumber.isNaN(x). - Conversion:
Number("42")→42;parseInt("42px", 10)→42;parseFloat("3.5rem")→3.5;(3.14159).toFixed(2)→"3.14"(a string). Mathhelpers:Math.round(4.5)=5,Math.floor(-1.2)=−2,Math.trunc(-1.2)=−1,Math.random()∈ [0,1).- Booleans: only
true/false. The eight falsy values arefalse,0,-0,0n,"",null,undefined,NaN; every other value, including[]and{}, is truthy.Boolean(x)or!!xforces conversion.
D. Strings and String Methods
A string is an immutable ordered sequence of UTF-16 code units, written with '…', "…" or backticks.
- Template literals:
`Total: ${price * qty}`interpolates expressions and spans lines directly. - Immutability:
s[0] = "H"silently fails; every method returns a new string. - Inspection:
.length,s[2],.charAt(2),.indexOf("a")(−1 if absent),.includes("ab"),.startsWith,.endsWith. - Extraction:
.slice(2, 5)(negative indices count from the end),.substring(2, 5)(clamps negatives to 0). - Transformation:
.toUpperCase(),.toLowerCase(),.trim(),.replace("a","b")(first match),.replaceAll,.repeat(3),.padStart(5,"0"). - Splitting and joining:
"a,b,c".split(",")→["a","b","c"]; the inverse isarr.join(","). - Escapes:
\nnewline,\ttab,\\backslash,\"quote.
III. Expressions and Operations
A. Operators and Expressions
An expression is any fragment that produces a value; operators combine operands into expressions.
- Arithmetic:
+ - * / % ** ++ --.%is remainder, keeping the dividend's sign (-7 % 3→-1);**is right-associative (2 ** 3 ** 2= 512). - Assignment:
=, and compounds+=,-=,*=,/=,%=,**=. - Comparison:
==(loose): coerces before comparing —"5" == 5istrue,null == undefinedistrue.===(strict): compares type and value —"5" === 5isfalse. Always prefer===.
- Logical:
&&,||,!.&&and||short-circuit and return an operand, not a boolean:"" || "default"→"default". - Nullish coalescing
??: returns the right side only fornull/undefined, so0 ?? 10→0while0 || 10→10. - Ternary:
const fee = age < 18 ? 0 : 100; - Overloaded
+: if either operand is a string,+concatenates:1 + "2"→"12", but1 - "2"→-1. - Precedence: grouping
()> unary!/++>**>* / %>+ -> comparison >&&>||/??>=.
B. Conditional Statements
Conditional statements select which block executes by evaluating a condition to a truthy or falsy value.
if / else if / else: conditions are tested top-down and the first truthy branch runs.switch: compares with strict equality against eachcase;breakis mandatory or execution falls through.
switch (grade) {
case "A":
case "B": message = "Pass"; break; // deliberate fall-through
default: message = "Fail";
}- Guard clauses:
if (!user) return;early exits flatten nesting. - Common pitfall:
if (x = 5)assigns and is always truthy; the intended test isif (x === 5).
IV. Functions and Scope
A. Functions
A function is a reusable, parameterised block that is itself a first-class value — assignable, passable and returnable.
- Declaration:
function add(a, b) { return a + b; }— hoisted entirely, so it may be called before its definition. - Expression:
const add = function (a, b) { return a + b; };— bound byconst, so it is not callable earlier. - Arrow function (ES6):
const add = (a, b) => a + b;— implicit return when the body is a single expression; has no ownthis,arguments, and cannot be a constructor. - Parameters: missing arguments become
undefined; defaultsfunction greet(name = "guest"); restfunction sum(...nums)collects extras into a real array. - Return: a function without
returnyieldsundefined;returnimmediately terminates execution. - Callbacks: functions passed as arguments, e.g.
[1,2,3].map(n => n * 2)→[2,4,6].
B. Scope
Scope is the region of code in which a binding is visible; JavaScript resolves names lexically, by where code is written, not where it is called.
- Global scope: declared outside any function; attached to
windowin browsers. Pollution risks name collisions. - Function scope:
varand parameters live for the whole function body. - Block scope:
let/constare confined to the nearest{ }, including loop bodies andifblocks. - Scope chain: an inner scope reads outer bindings, never the reverse; lookup walks outward until the global scope, then throws
ReferenceError. - Hoisting: declarations move to the top of their scope —
varinitialised toundefined,let/constleft in the temporal dead zone. - Closure: an inner function retains access to its defining scope after the outer call returns.
function counter() {
let n = 0; // private to the closure
return () => ++n;
}
const next = counter();
next(); next(); // 1, then 2V. Structured Data
A. Arrays and Array Operations
An array is an ordered, zero-indexed, dynamically sized object whose length is one more than its highest index.
- Creation and access:
const a = [10, 20, 30]; a[0]→10;a[-1]isundefined, so usea.at(-1)ora[a.length-1]. - Mutating operations:
push/popat the end,unshift/shiftat the front,splice(1, 2, "x")removes 2 items from index 1 and inserts"x",sort,reverse. - Non-mutating:
slice(1,3),concat,join("-"),indexOf,includes. - Iteration methods:
forEach(side effects),map(transform, same length),filter(subset),find(first match),reduce(fold to one value),some/every(boolean tests).
const cart = [{p:100}, {p:250}];
const total = cart.reduce((sum, item) => sum + item.p, 0); // 350- Sorting caveat:
sort()compares as strings, so[10,9,1].sort()→[1,10,9]; supply a comparatorsort((a,b) => a - b). - Copying:
[...a]ora.slice()creates a shallow copy;const b = amerely aliases the same array.
B. Objects and Object Manipulation
An object is an unordered collection of key–value pairs, where keys are strings or symbols and values may be any type, including functions (methods).
- Literal and access:
const u = { name: "Asha", age: 21 };— dot notationu.name; bracket notationu["age"]is required for dynamic or non-identifier keys (u[key]). - Mutation: add or update with
u.city = "Pune"; remove withdelete u.age; test with"name" in uoru.hasOwnProperty("name"). - Methods and
this: insidegreet() { return "Hi " + this.name; },thisrefers to the object the method is called on. - Enumeration:
Object.keys(u),Object.values(u),Object.entries(u)return arrays;for (const k in u)iterates keys including inherited ones. - Copying and merging:
{ ...defaults, ...options }andObject.assign({}, a, b)— both shallow, so nested objects stay shared. - Destructuring:
const { name, city = "N/A" } = u;extracts with a fallback; shorthand{ name, age }builds an object from like-named variables. - Safe access:
u.address?.pinreturnsundefinedinstead of throwing whenaddressis absent. - Prototypes: every object links to a prototype object, from which it inherits properties — the basis of JavaScript's object model, with
classsyntax as sugar over it.
Did this save you a night before the exam?
LPU Notes is free, and it stays free. Ads cover part of the server bill. The rest comes out of a student's own pocket: the domain, the storage, and keeping the site up through the weeks everyone needs it at once.
The payment button didn't load. An ad blocker or a filtered network is the usual reason. to try again.
Nothing here is ever locked, and nothing unlocks. Chip in only if it was worth it. What it pays for →