Skip to content

Latest commit

 

History

History
81 lines (64 loc) · 3.75 KB

NOTES.md

File metadata and controls

81 lines (64 loc) · 3.75 KB

Notes — Advanced JavaScript

Condensed explanations for each acceptance criterion. Code references point into the corresponding annotated file.

1. The prototype chain

Every object has an internal [[Prototype]] link to another object (or null). Property lookup checks the object itself first, then walks up the chain until the property is found or the chain ends at null.

  • Function.prototype is the object that becomes the [[Prototype]] of instances created with new SomeFunction().
  • obj.__proto__ is the (legacy but still common) accessor for an object's actual [[Prototype]]; Object.getPrototypeOf(obj) is the modern equivalent.
  • class/extends are syntax sugar over the same prototype-linking mechanism — extends sets Child.prototype's [[Prototype]] to Parent.prototype.
  • Methods defined on a prototype are shared by all instances (one copy in memory); properties set with this.x = inside a constructor are per-instance.

Reference: 01-prototypes.js

2. ES6+ syntax

  • Destructuring pulls values out of arrays/objects into variables, including with renaming, defaults, and nested patterns.
  • Spread (...) expands an iterable/object into individual elements/properties — used in array/object literals and function calls.
  • Rest (...) is the inverse — collects remaining items into a single array, only valid as the last function parameter or in a destructuring pattern.
  • Optional chaining (?.) short-circuits to undefined instead of throwing when accessing a property/method on null/undefined.
  • Nullish coalescing (??) provides a default only for null/undefined — unlike ||, it does not treat 0, "", or false as missing.

Reference: 02-es6-plus.js

3. Iterators and generators

  • An iterable has a Symbol.iterator method returning an iterator.
  • An iterator is any object with .next() returning { value, done }.
  • for...of, spread, and destructuring all work on anything iterable.
  • A generator function (function*) is a shortcut for writing an iterator: each call returns a generator object, and yield pauses execution, returning a value, until .next() is called again.
  • yield* delegates iteration to another iterable/generator.
  • Generators are lazy — values are only produced when requested, which is what makes infinite sequences (like naturalNumbers()) practical.

Reference: 03-iterators-generators.js

4. ES modules vs CommonJS

  • ES modules (import/export) are static — resolved at parse time, which enables tree-shaking, and always run in strict mode.
  • CommonJS (require/module.exports) is dynamic — require() is a regular function call, evaluated synchronously at runtime, which allows conditional requires but blocks tree-shaking.
  • ES modules support asynchronous, lazy loading via import(); CommonJS require() is always synchronous and blocks until the module is fully evaluated.
  • Node.js supports both; the choice is signaled by file extension (.mjs/.cjs) or the "type" field in package.json.

Reference: 04-modules-notes.md, es-modules-example/, commonjs-example/

5. Design patterns

  • Module pattern: an IIFE closure that exposes only the public API, keeping internal state private.
  • Singleton: a class that hands back the same instance on every construction call, guaranteeing exactly one instance exists.
  • Factory: a function that builds and returns different object shapes based on input, without exposing constructor/new details to the caller.
  • Observer: an object (EventEmitter) that lets other code subscribe to named events and get notified when they fire — decouples the event source from its reactions.

Reference: 05-design-patterns.js