main.jsCourse

JavaScript

What typeof reports, then an object, a class, why const does not freeze fields, and why a method needs the object it came from.

typeof reports the kind of value
  1. 450numbertypeof
  2. lattestringtypeof
  3. truebooleantypeof

6 lessons, in orderFree to read

Syllabus

Basics

The types, explained, then an object you can name and call.

  1. typeof reports the type of a value. A latte label uses a number, a string, and a boolean. The program prints latte $4.50 ready, then number string boolean.

    const name = "latte";
    const cents = 450;
    const ready = true;
    const status = ready ? "ready" : "sold out";
    const frac = String(cents % 100).padStart(2, "0");
    console.log(name + " $" + Math.floor(cents / 100) + "." + frac + " " + status);
    console.log(typeof cents, typeof name, typeof ready);
    latte $4.50 ready
    number string boolean
    
  2. An object groups named fields. A latte has a name and a price in cents. The program prints latte $4.50.

    Builds on lesson 1.

    const item = { name: "latte", cents: 450 };
    const frac = String(item.cents % 100).padStart(2, "0");
    console.log(item.name + " $" + Math.floor(item.cents / 100) + "." + frac);
    latte $4.50
    

Practice

A rule that prevents a bug, then a program that uses the object.

  1. A class puts the fields and the method on one object. new Item makes a latte. label prints latte $4.50.

    Builds on lessons 1 through 2.

    class Item {
      constructor(name, cents) {
        this.name = name;
        this.cents = cents;
      }
    
      label() {
        const frac = String(this.cents % 100).padStart(2, "0");
        return this.name + " $" + Math.floor(this.cents / 100) + "." + frac;
      }
    }
    
    const latte = new Item("latte", 450);
    console.log(latte.label());
    latte $4.50
    
  2. const stops a new assignment to the name. It does not freeze the fields. A spread copies the drink. The original stays 450. The tipped copy is 540.

    Builds on lessons 1 through 3.

    const item = { name: "latte", cents: 450 };
    const tipped = { ...item, cents: 540 };
    console.log(item.cents, tipped.cents);
    450 540
    

Further

One more idea, then a program that puts the pieces together.

  1. Pulling a method off the object and calling it loses this. The detached call throws. Calling label on the latte prints latte $4.50.

    Builds on lessons 1 through 4.

    class Item {
      constructor(name, cents) {
        this.name = name;
        this.cents = cents;
      }
    
      label() {
        const frac = String(this.cents % 100).padStart(2, "0");
        return this.name + " $" + Math.floor(this.cents / 100) + "." + frac;
      }
    }
    
    const latte = new Item("latte", 450);
    const label = latte.label;
    let detached;
    try {
      detached = label();
    } catch (e) {
      detached = "lost";
    }
    console.log(detached);
    console.log(latte.label());
    lost
    latte $4.50
    
  2. A function can take the object and read the fields it needs. price takes a drink and returns the label. The program prints latte $4.50.

    Builds on lessons 1 through 5.

    function price(item) {
      const frac = String(item.cents % 100).padStart(2, "0");
      return item.name + " $" + Math.floor(item.cents / 100) + "." + frac;
    }
    
    const latte = { name: "latte", cents: 450 };
    console.log(price(latte));
    latte $4.50
    

Readings

Shorter pieces in the same language. Any order is fine once the lessons feel familiar.

  1. this: decided at the call site 3 min

    GoByte Skills #18: this is decided at the call site, not where the function is written. One function, three calls, three answers, and why arrows opt out.

  2. Closures: functions remember where they were born 2 min

    GoByte Skills #17: A closure captures the variable, not the value. That is why three callbacks in a var loop all print 3 and the let loop prints 0, 1, 2.

  3. The event loop: await does not block 3 min

    GoByte Skills #16: await suspends one function, not the thread. Six log lines, two queues, one fixed order, and why a setTimeout of 0 still waits for every microtask.