Skip to content
Chapter 04 · Slide Breakdown

JavaScript Fundamentals

The turning point of the course. Everything from here to chapter 7 is JavaScript, so a gap left in this chapter reappears in the DOM, in Node, and in your database queries. The array-function slides at the end are the ones you will use every single week.

64 slidesTwo decks in onePure write-itBook ch. 8 + 9

What this chapter is really for

Split at slide 55: Part 1 (1–54) is the language, Part 2 (55–64) is the six array functions. Part 2 is short, dense, and used constantly — do not let it get squeezed out by revision time.

Four properties of JavaScript are stated on slide 3 and they explain nearly every surprise in this chapter:

  1. It is an interpreted, object-oriented scripting language.
  2. It is primarily client-side. (Chapter 6 breaks this assumption with Node.)
  3. Functions are objects too — unlike Java, C# or C++. This is what makes callbacks, map, filter and event handlers possible.
  4. It is dynamically (weakly) typed: variables convert implicitly between types. This is what makes == dangerous and truthiness a topic.

Where the marks concentrate

Predict-the-output questions. Hoisting, truthiness, var vs let scope, == vs ===, primitive vs reference copying, and what sort() does to numbers. Each is a small slide and a reliable question.

Where it connects

Objects and JSON here become the data your fetch calls return in chapter 6 and your database documents in chapter 7. Callbacks here become event handlers in chapter 5 and asynchronous code in chapter 6. This chapter is the spine.

All 64 slides, weighted

SlidesTopicWeightWhat to do with it
1–3Objectives; what JavaScript isMemorizeFour properties: interpreted and object-oriented, primarily client-side, functions are objects, dynamically typed.
4–6Client-side scripting advantages and disadvantagesMemorizeThree advantages, four disadvantages. The sharpest one: JavaScript is not fault tolerant — browsers forgive bad HTML and CSS but stop at an invalid line of JS.
7–9Inline, embedded and external JavaScript; execution orderWrite itExternal is recommended. Scripts run in the order encountered on the page, whether inline or external.
10–12Variables; alert/prompt/confirm; document.write/console.logWrite itKnow all five output methods. Note the copy-paste warning about smart quotes — it is a real cause of lab errors.
13–15Primitive vs reference types; copyingMemorizeSix primitives. Primitives hold the value; objects hold a reference. structuredClone() deep copies, [...foo] copies shallowly.
16let vs constMemorizeScreenshot slide — the comparison is reconstructed below.
17Built-in objectsMemorizeObject, Function, Boolean, Error, Number, Math, Date, String, RegExp. Browser-only: document, console, navigator, window.
18Concatenation and template stringsWrite itThe console.log outputs on this slide are a predict-the-output question waiting to happen.
19–21Conditionals, switch, ternary, truthy and falsyMemorizeLearn the falsy list exactly — there are seven values and everything else is truthy.
22–24while, do…while, for, try…catchWrite itStandard, but write them once so the syntax is automatic.
25–29Arrays: literal and constructor, iteration, destructuringWrite itSlide 29 is a trick question about length — work out why before reading the answer.
30–36Objects: literal notation, constructor, nesting, destructuringWrite itJavaScript is prototype based: objects come from other objects, not from classes. Literal notation is preferred.
37–38JSON and the JSON objectMemorizeThe difference from object literals is exactly one thing: JSON property names are quoted. And JSON is a string until you parse it.
39–43Functions, expressions, default and rest parametersWrite itDeclaration vs expression matters for hoisting on the next slide. ...args is the rest operator.
44HoistingMemorizeDeclarations are hoisted; assignments are not. That second half is where the marks are.
45–48Callback functions; the map exerciseWrite itSlide 46 is flagged on the slide itself as very important — the basis of all functional programming. Implement it.
49–50Objects with function properties; constructors as functionsWrite itThe this keyword. Without it, the properties are simply not defined inside the method.
51Arrow syntaxWrite itConcise anonymous functions. One restriction stated on the slide: arrow functions cannot be used as constructors.
52–54Scope: function, block, module, globalMemorizeThe examinable contrast: let/const respect block scope, var does not.
55–56Part 2 title; the six array functionsMemorizeOne line each for forEach, find, filter, map, reduce, sort. Learn what each returns.
57–62Each array function with worked examplesWrite itThe paintings array on slide 62 is the reference example. Reproduce every operation on it.
63–64Home task; array syntax overviewWrite itDo the reduce task — it is five minutes and it locks in the hardest of the six.

Placement, output, types and truthiness

Where JavaScript goes

js-placement.htmlSlides 7–9[ RUN IT → ]
<!-- 1. INLINE — inside an HTML attribute -->
<button onclick="alert('hi')">Click</button>

<!-- 2. EMBEDDED — a <script> element in the document -->
<script>
    console.log('runs where it sits');
</script>

<!-- 3. EXTERNAL — RECOMMENDED -->
<script src="myscripts/external.js"></script>

EXECUTION ORDER: it does not matter whether a script is external or
inline — they execute IN THE ORDER ENCOUNTERED on the page. Which is why
a script that touches the DOM belongs at the END of <body>, or must wait
for DOMContentLoaded (chapter 5).

Five ways to produce output

output.jsSlides 11–12
let answer = prompt("Please enter your name:");   // message + input field
alert('your name is ' + answer);                    // pop-up / modal
let ok = confirm("Are you sure?");                 // ok / cancel → true or false

document.write('<h1>your name is ' + answer + '</h1>');  // writes MARKUP into the page
console.log(answer);                                 // the browser's JS console

// WARNING from slide 10: copying code can turn straight quotes into
// smart quotes ( ' " ) which are NOT valid JavaScript. If a pasted line
// throws for no visible reason, retype the quotes.

Types

Two basic kinds: reference types (objects) and primitive types.

PrimitiveMeaning
booleanTrue or false.
numberA double precision 64-bit floating point value.
bigintAn integer that can be very large (greater than 253).
stringA sequence of characters delimited by single or double quotes.
nullHas exactly one value: null.
undefinedHas exactly one value. Assigned to variables that are not initialised. Different from null.
primitive-vs-reference.jsSlides 13–15[ RUN IT → ]
// PRIMITIVE variables hold the VALUE directly in memory.
let a = 5;
let b = a;      // b gets its own copy
b = 10;
console.log(a);  // 5  — unaffected

// OBJECT variables hold a REFERENCE (a pointer) to the block of memory.
const years = [1855, 1648, 1420];
const myYear2 = years;        // BOTH names point at the SAME array
myYear2.push(2026);
console.log(years.length);   // 4  — the "other" array changed too

// Copying properly:
const shallow = [...years];               // spread — a new array, one level deep
let deepCopy = structuredClone(original); // a full, independent deep copy

var vs let vs const

varletconst
ScopeFunction scope — leaks out of if and for blocks.Block scope.Block scope.
Reassign?Yes.Yes.No — the binding cannot be reassigned.
Redeclare?Yes, silently.No.No.
Hoisted?Declaration hoisted, initialised as undefined.Hoisted but unusable before its line.Same as let.
Use it?Avoid.When the value changes.Default choice.
Careful with const and objects: const freezes the binding, not the contents. const a = [1,2]; a.push(3); is perfectly legal — you changed what the reference points to, not which object it points at. a = [4] is the error.

Truthy and falsy

truthy.jsSlide 21
// Everything in JavaScript has an inherent boolean value.
// EXACTLY SEVEN values are falsy. Everything else is truthy.

//   false      null      ""      ''      0      NaN      undefined

// Consequences that catch people out — all of these are TRUTHY:
Boolean([]);          // true  ← an empty array
Boolean({});          // true  ← an empty object
Boolean("0");       // true  ← a non-empty STRING
Boolean("false");   // true  ← also just a string
Boolean(-1);         // true  ← only ZERO is falsy

// The slide's own test — !! converts to a boolean:
let a = 2;
let b;              // declared but not initialised → undefined
!!a;               // true   → a is truthy
!a;                // false
!!b;               // false  → undefined is falsy

// Practical use, straight from slide 19:
if (!answer) console.log('the answer is empty');
else        console.log('Great: ' + answer);

// Same thing as a ternary (slide 20):
console.log( (!answer) ? 'the answer is empty' : 'Great: ' + answer );

Slide 20 also gives an opinion worth repeating in an exam: better to avoid the switch syntax because it can easily lead to errors — the fall-through problem when a break is forgotten.

Loops and exceptions

loops.jsSlides 22–24[ RUN IT → ]
// while — initialise before, test in the condition, modify inside
let count = 0;
while (count < 10) { count++; }

// do…while — the body always runs AT LEAST ONCE
count = 0;
do { count++; } while (count < 10);

// for — initialisation ; condition ; post-loop, all in one statement
for (let i = 0; i < 10; i++) { }

// try…catch — JavaScript is NOT fault tolerant: an uncaught runtime
// error stops execution at that line. This is how you prevent that.
try {
    nonexistantfunction("hello");
} catch (err) {
    alert("An exception was caught:" + err);
}

Arrays, objects and JSON

Arrays

arrays.jsSlides 25–28[ RUN IT → ]
// TWO ways to define one
const years = [1855, 1648, 1420];              // literal notation — preferred
const years2 = new Array(1855, 1648, 1420);   // Array() constructor

// Copy vs alias — slide 26
const myyear  = [...years];  // a NEW array with the same elements
const myyear2 = years;       // BOTH variables point to the SAME array

// Arrays may hold mixed types, and may be multi-dimensional
const mess = [53, "Canada", true, 1420];
const twoWeeks = [
    ["Mon","Tue","Wed","Thu","Fri"],
    ["Mon","Tue","Wed"]
];

// ITERATION — for…of (ES6) and its classic equivalent
for (let yr of years) console.log(yr);
for (let i = 0; i < years.length; i++) console.log(years[i]);

// DESTRUCTURING — slide 28. These two blocks are equivalent.
const league = ["Liverpool", "Man City", "Arsenal", "Chelsea"];
let first = league[0], second = league[1], third = league[2];
let [a, b, c] = league;   // one line instead of three

Slide 29 — "who will answer?"

Given the ragged twoWeeks array above, the slide asks for twoWeeks.length(), twoWeeks[0].length() and twoWeeks[1].length(). All three as written throw a TypeError, because length is a property, not a method — there are no parentheses. Written correctly, twoWeeks.length is 2 (two rows), twoWeeks[0].length is 5 and twoWeeks[1].length is 3. The array being ragged is the whole point of the question.

Objects

JavaScript objects are a collection of named values, called properties. Unlike C++ or Java, they are not created from classes — JavaScript is prototype based, and new objects come from existing prototype objects.

01-creation.jsSlides 30–34[ RUN IT → ]
// LITERAL NOTATION — the most common way, and the preferred one
const objName = {
    name1: 'value1',      // key : value, pairs separated by commas
    name2: 'value2'
};

// Two ways to reach a property
objName.name1;         // dot notation
objName["name1"];      // square bracket notation (needed for dynamic keys)

// OBJECT CONSTRUCTOR — the other way. Literal notation is preferred.
const obj2 = new Object();
obj2.name1 = 'value1';

// NESTED OBJECTS — the slide 34 exercise, done
let ksa = {
    id: '966',
    name: 'KSA',
    currency: {
        name: 'riyal',
        valueAgainstDollar: 0.2666,
        coins:      [0.01, 0.05, 0.1, 0.2, 0.5],
        banknotes:  [1, 5, 10, 20, 50, 100, 200, 500]
    }
};
console.log(ksa.currency.coins[0]);   // 0.01
03-object-destructuring.jsSlides 35–36[ RUN IT → ]
const photo = {
    id: 1,
    title: "Central Library",
    location: { country: "Canada", city: "Calgary" }
};

// The long way
let id = photo.id;
let title = photo.title;
let country = photo.location.country;
let city = photo.location.city;

// Destructured — YOU MUST USE THE PROPERTY NAME. Unlike arrays,
// objects are matched by NAME, not by position.
let { id, title } = photo;
let { country, city } = photo.location;

// …and both in one statement
let { id, title, location: { country, city } } = photo;

JSON

json.jsSlides 37–38[ RUN IT → ]
// JSON = a language-independent data interchange format, used the way
// XML is used. The ONE syntactic difference from an object literal:
// PROPERTY NAMES ARE ENCLOSED IN QUOTES.

// This is a STRING that happens to look like an object:
const text = '{ "name1": "value1", "name2": "value2" }';
text.name1;   // undefined — it is still just a string!

// JSON.parse turns the string into a real JavaScript object
const anObj = JSON.parse(text);
console.log(anObj.name1);      // "value1"

// …and JSON.stringify goes the other way, for sending data to a server
const back = JSON.stringify(anObj);

// The slide 38 example: an array of JSON strings into an HTML table
const countries = ['{"id": "01", "name": "KSA"}',
                   '{"id": "02", "name": "Japan"}',
                   '{"id": "03", "name": "Oman"}'];

document.write('<table><tr><th>ID</th><th>Country</th></tr>');
for (let c of countries) {
    let co = JSON.parse(c);
    document.write('<tr><td>' + co.id + '</td><td>' + co.name + '</td></tr>');
}
document.write('</table>');
The JSON question, every time: is it a string or an object? Quoted keys and wrapped in ' ' means it is a string and you cannot use dot notation until JSON.parse() has run. Everything a fetch() returns in chapter 6 arrives in exactly this state.

Functions, callbacks, hoisting and scope

Declarations, expressions, defaults and rest

functions.jsSlides 39–42[ RUN IT → ]
// FUNCTION DECLARATION
function subtotal(price, quantity) {
    return price * quantity;
}
let result = subtotal(10, 2);   // invoked with the () operator

// FUNCTION EXPRESSION — an ANONYMOUS function assigned to a variable
const calculateSubtotal = function (price, quantity) {
    return price * quantity;
};

// DEFAULT PARAMETERS — slide 41
function foo(a, b) { return a + b; }
let bar = foo(3);              // 3 + undefined  →  NaN

function foo2(a = 10, b = 0) { return a + b; }
let bar2 = foo2(3);            // 3 + 0  →  3

// REST PARAMETERS — an indeterminate number of arguments, via ...
function concatenate(...args) {
    let s = "";
    for (let a of args) s += a + " ";
    return s;
}
concatenate("fatima", "hema", "jane", "alia");  // "fatima hema jane alia "
concatenate("jamal", "nasir");                    // "jamal nasir "

let sum = function (...args) { let s = 0; for (let e of args) s += e; return s; };

Hoisting — the half people forget

hoisted.jsSlide 44[ RUN IT → ]
// Function DECLARATIONS are hoisted to the top of their level,
// so this works even though the call comes first:
greet();                          // "hi"  ✓
function greet() { console.log("hi"); }

// Function EXPRESSIONS are not — the VARIABLE is hoisted, the
// ASSIGNMENT is not. THE ASSIGNMENTS ARE NOT HOISTED.
greet2();                         // TypeError: greet2 is not a function  ✗
const greet2 = function () { console.log("hi"); };

// Same rule for variables:
console.log(x);                   // undefined  ← declaration hoisted, value not
var x = 5;
console.log(x);                   // 5

// with let/const you get an error instead of undefined:
console.log(y);                   // ReferenceError
let y = 5;

Callbacks — and the exercise the slides call essential

Because functions are objects, a function can be passed as an argument to another function. That passed function is a callback. Slide 46 marks its exercise as very important to understand — the basis of all functional programming, so here it is in full.

map-exercise.jsSlides 45–48[ RUN IT → ]
// A map function that applies any given function to any number of
// input lists, returning an array of the results.
let map = function (f, ...args) {      // f is the CALLBACK; ...args the lists
    let s = [], i = 0;
    for (let e of args) s[i++] = f(e);  // call f on each list
    return s;
};

let sum = function (a) {
    let s = 0;
    for (let e of a) s += e;
    return s;
};

map(sum, [3, 5, 6], [4, 7, 8], [8, 5]);   // → [14, 19, 13]

// The home task on slide 47: write three more callbacks for the same map.
let multiply = a => a.reduce((p, e) => p * e, 1);
let average  = a => sum(a) / a.length;
let max      = function (a) { let m = a[0]; for (let e of a) if (e > m) m = e; return m; };

map(multiply, [3, 5, 6], [4, 7, 8]);   // → [90, 224]
map(average,  [3, 5, 6]);                // → [4.666…]
map(max,      [3, 5, 6], [8, 5]);         // → [6, 8]

// Slide 48: you can define the callback DIRECTLY in the invocation
map(function (a) { return a.length; }, [3, 5, 6], [4]);  // → [3, 1]

this, and constructors as functions

this-and-constructors.jsSlides 49–50[ RUN IT → ]
// Objects can have properties that ARE functions.
// Inside them, `this` refers to the object that owns the function.
// WITHOUT `this`, brand and price are simply NOT DEFINED.
const order = {
    salesDate: "May 5, 2016",
    product: {
        price: 500.00,
        brand: "Acer",
        output: function () { return `${this.brand}, ${this.price}$`; }
    },
    customer: {
        name: "Ward Jondob",
        address: "123 Chamal St, Najran",
        output: function () { return `${this.name}, ${this.address}`; }
    }
};
alert(order.product.output());     // "Acer, 500$"
alert(order.customer.output());

// A CONSTRUCTOR is just a function that assigns to `this`.
// Convention: capitalise its name. Create instances with `new`.
function Customer(name, address, city) {
    this.name = name;
    this.address = address;
    this.city = city;
    this.output = function () { return `${this.name}, ${this.address}, ${this.city}`; };
}
const cust1 = new Customer("Ward Jondob", "123 Chamal Street", "Najran");
alert(cust1.output());

Arrow syntax

arrows.jsSlide 51
// The same function, three ways
const taxRate = function () { return 0.05; };   // expression
const taxRate = () => { return 0.05; };          // arrow, explicit return
const taxRate = () => 0.05;                     // arrow, IMPLICIT return

// With parameters
(a, b) => { return a + b; }
(a, b) => a + b                // no braces = the expression IS the return value
a => a * 2                    // one parameter: the parentheses are optional

// RESTRICTION stated on the slide: arrow functions CANNOT be used as
// constructors. `new` on an arrow function throws.

Scope

JavaScript has four scopes: function (local), block, module and global.

scope.jsSlides 52–54[ RUN IT → ]
// BLOCK SCOPE — let and const are confined to the { } they appear in.
// var is NOT: declared with var inside a block, it is available outside.
if (true) {
    let   blockOnly = "invisible outside";
    const alsoBlock = "invisible outside";
    var   leaks     = "visible outside!";
}
console.log(leaks);       // "visible outside!"  ← the var problem
console.log(blockOnly);   // ReferenceError

// FUNCTION / LOCAL SCOPE — everything declared in a function is
// invisible outside it, whichever keyword you use.
function f() { var local = 1; }
console.log(local);       // ReferenceError

// The classic loop demonstration
for (var i = 0; i < 3; i++) { }
console.log(i);           // 3   ← var survives the loop
for (let j = 0; j < 3; j++) { }
console.log(j);           // ReferenceError  ← let does not

The six array functions — Part 2

Short deck, enormous payoff. These six replace almost every loop you would otherwise write, and they appear again in chapter 5 (transforming NodeLists) and chapter 7 (shaping database results).

The slides use one reference array throughout. Everything below runs against it.

paintings.js — the reference dataSlide 62
const paintings = [
    {title: "Girl with a pearl earring",  artist: "Vermeer",  value: 10},
    {title: "Artists Holding a Thistle",  artist: "Durer",    value: 7},
    {title: "Wheat field with Crows",     artist: "Van Gogh", value: 16},
    {title: "Burial at Ornans",           artist: "Courbet",  value: 18},
    {title: "Wheat field with Crows",     artist: "Van Gogh", value: 9}
];
FunctionWhat it doesWhat it RETURNS
forEach()Iterates through the array.Nothing (undefined). Use it for side effects only.
find()Finds the first element whose property matches a condition.That one element, or undefined.
filter()Finds all elements matching a condition.A new array — possibly empty.
map()Transforms every element by the passed function.A new array of the same size.
reduce()Collapses the array by combining elements.A single value.
sort()Sorts a one-dimensional array in place, ascending, converting to strings by default.The same (now mutated) array.
array-functions.jsSlides 56–63[ RUN IT → ]
// ── forEach: iterate. Returns nothing. ──────────────────────────
paintings.forEach(p => console.log(p.title));

// ── find: the FIRST match, or undefined ─────────────────────────
const courbet = paintings.find( p => p.artist === 'Courbet' );
console.log(courbet.title);            // "Burial at Ornans"
// the callback must return TRUE (matches) or FALSE (does not).

// ── filter: ALL matches, as a new array ─────────────────────────
const vanGoghs = paintings.filter( p => p.artist === 'Van Gogh' );
console.log(vanGoghs.length);          // 2

// ── map: same size, transformed values ──────────────────────────
const titles = paintings.map( p => p.title );   // 5 strings

// The slide 59 example, with a regular expression (chapter 5)
const arr = ["hello", "selem", "ciao", "hallo", "gutentag"];
const pat = /el/;
arr.map(o => pat.test(o));      // [true, true, false, false, false]  ← SAME SIZE
arr.filter(o => pat.test(o));   // ['hello', 'selem']                ← FEWER

// ── reduce: array → one value ───────────────────────────────────
//   (prev, current) => …          prev carries the running result
//   the last argument is the INITIAL value of prev
let initial = 0;
const total = paintings.reduce( (prev, p) => prev + p.value, initial );
console.log(total);                    // 60

const all = arr.reduce( (prev, p) => prev + " " + p );
// 'hello selem ciao hallo gutentag'  ← no initial value: prev starts as arr[0]

// the slide 63 home task: multiply every element
const product = [2, 3, 4].reduce( (prev, e) => prev * e, 1 );   // 24

// ── sort: IN PLACE, and stringly by default ─────────────────────
arr.sort();     // ['ciao','gutentag','hallo','hello','selem']  — fine for strings

const numberArray = [40, 5, 200, 1];
numberArray.sort();                    // [1, 200, 40, 5]   ← WRONG. Sorted as text!

function compareNumbers(a, b) { return a - b; }
numberArray.sort(compareNumbers);      // [1, 5, 40, 200]   ← correct

// A comparator returns:  0 if equal,  positive if a > b,  negative if a < b
const compareFn = (a, b) => a.value - b.value;
paintings.sort(compareFn);             // by value, ascending

// sort() MUTATES. Use toSorted() to leave the original alone.
const sortedCopy = paintings.toSorted(compareFn);
Pick the right one by asking what you want back. Nothing → forEach. One element → find. Fewer elements → filter. The same number, changed → map. One value → reduce. The same array, reordered → sort.

The eight things people get wrong

sort() on numbers

[40, 5, 200, 1].sort() gives [1, 200, 40, 5]. By default sort() converts elements to strings, and "200" sorts before "40" because "2" comes before "4".

Fix: Always pass a comparator for numbers: arr.sort((a,b) => a - b). And remember it sorts in place — the original array is modified. Use toSorted() if you need it intact.

Expecting forEach to return something

const doubled = arr.forEach(x => x * 2) leaves doubled as undefined. forEach exists for side effects and returns nothing.

Fix: If you want a result, use map. If you want fewer items, use filter. If you want one value, use reduce.

Hoisting only half-remembered

People learn "declarations are hoisted" and assume everything works. But calling a function expression before its line gives TypeError: not a function, and reading a var before its line gives undefined rather than an error.

Fix: Declarations move; assignments do not. Function declarations are callable early; function expressions are not.

var escaping a block

A var declared inside an if or a for is visible after the block ends, and a loop counter declared with var still exists afterwards. This is exactly the contrast slide 53 draws.

Fix: Use const by default and let when the value changes. Both respect block scope.

Forgetting this inside an object method

Writing return `${brand}, ${price}` instead of ${this.brand} throws, because brand is not a variable in scope — it is a property of the object. The slide says so explicitly.

Fix: Inside a method, reach the object’s own properties through this. And do not use an arrow function as an object method if you need this.

Treating a JSON string as an object

text.name1 on a JSON string is undefined, silently. The quotes around the whole thing make it a string, and strings do not have your properties.

Fix: JSON.parse() first, then use dot notation. JSON.stringify() to go back.

Copying an array by assigning it

const copy = original creates a second name for the same array. Changing one changes both, because object variables hold a reference, not the value.

Fix: [...original] for a shallow copy, structuredClone(original) for a deep one.

Assuming empty things are falsy

[] and {} are truthy, so if (myArray) is true even for an empty array. So is the string "0".

Fix: There are exactly seven falsy values: false, null, "", '', 0, NaN, undefined. Test emptiness with arr.length === 0.

Chapter 4 on a single screen

Primitives

  • boolean number bigint
  • string null undefined
  • Everything else is a reference type (object)
  • Primitive holds the value; object holds a reference

Falsy — all seven

  • false
  • null · undefined
  • "" · ''
  • 0 · NaN
  • Everything else is truthy, including [] and {}

Declarations

  • const — block scope, no reassign (default)
  • let — block scope, reassignable
  • var — function scope, leaks. Avoid.
  • Declarations hoist; assignments do not

Output

  • alert() — modal message
  • prompt() — message + input
  • confirm() — ok / cancel
  • document.write() — markup into the page
  • console.log() — the JS console

Arrays

  • [a, b] literal · new Array(a, b)
  • for (let x of arr)
  • let [a, b] = arr destructure by POSITION
  • [...arr] shallow copy
  • arr.length — a property, no ()

Objects

  • { key: value } literal (preferred)
  • obj.key or obj["key"]
  • let {a, b} = obj destructure by NAME
  • Prototype based — no classes
  • this inside a method

JSON

  • Keys are quoted
  • A JSON string is a string
  • JSON.parse(str) → object
  • JSON.stringify(obj) → string

Functions

  • function f() {} declaration (hoisted)
  • const f = function () {} expression
  • const f = (a) => a * 2 arrow
  • function f(a = 10) default
  • function f(...args) rest
  • Arrows cannot be constructors

Array functions

  • forEach → nothing
  • find → first match
  • filter → array of matches
  • map → same size, transformed
  • reduce(fn, init) → one value
  • sort(cmp) → in place; needs a comparator for numbers

Predict the output, then run it

This chapter is examined with predict-the-output questions, so practise it that way: write your answer down before pressing run. Being wrong and knowing why is the whole exercise.

  1. Write down what [40, 5, 200, 1].sort() produces, then run it, then fix it with a comparator.
  2. Predict the output of the concatenation example on slide 18 — both console.log calls — before you run it.
  3. Write six expressions, three truthy and three falsy, that a classmate would guess wrong. Use [], {} and "0".
  4. Call a function declaration before its definition, then convert it to an expression and observe the different error.
  5. Write the same loop with var and with let, then log the counter after the loop in each case.
  6. Copy an array by assignment, mutate the copy, and prove the original changed. Then fix it two ways.
  7. Build the KSA object from slide 34 from memory, then read ksa.currency.banknotes[3].
  8. Destructure that object’s name and its currency’s name in one statement — work out what to do about the name collision.
  9. Take a JSON string, try to read a property directly, then parse it and read the same property.
  10. Implement the slide 46 map function from memory, then write multiply, average and max callbacks for it.
  11. Write an object with a method that uses this, then delete the this and read the error message carefully.
  12. Write a constructor function, create two instances, and give each one a different value.
  13. Convert three function expressions to arrow syntax, one with implicit return.
  14. On the paintings array: total the values with reduce, list the Van Goghs with filter, get all titles with map, and sort by value.
  15. Write the same "find all paintings worth more than 10" three ways — a for loop, filter, and reduce — and decide which reads best.

The full example set for this chapter is at chapter-4/javascript-codes/, and there are three graded tutorials in your study material: variables, if and loops, functions and JSON objects, and more on array methods. There is also an exercise set with questions.

Can you answer these without scrolling up?

Question 1