JavaScript 08 · JavaScript in general
Modules and built-in tools
import/export, JSON, Math, Date, Intl, localStorage and classes in a nutshell.
Loading lesson…
JavaScript 08 · JavaScript in general
import/export, JSON, Math, Date, Intl, localStorage and classes in a nutshell.
Loading lesson…
A big project is like a workshop. If all the tools lay in one heap, you'd never find anything. So each kind has its own labelled drawer – and when you need a screwdriver, you open the "screwdrivers" drawer. In JavaScript the drawers are modules: every file keeps its things to itself and only "lends out" what it explicitly exports.
The second half of the lesson is a tour of the tools JavaScript comes with: JSON, Math, Date, Intl, localStorage and classes. You don't need to know them by heart – it's enough to know they exist and how to find them.
Every file is a separate module. The variables and functions in it are private until you export them. There are two kinds of export:
// math.jsexport const PI = 3.14159 // a named export (there can be many)export function add(a, b) { return a + b }function secret() { … } // without export – not reachable from outsideexport default function multiply(a, b) { // the default export (only one per file)return a * b}
// app.jsimport multiply, { PI, add } from './math.js' // the default without braces, named ones in { }import times from './math.js' // you can name the default whatever you likeimport { add as plus } from './math.js' // rename a named one with asimport * as math from './math.js' // everything under one name: math.add, math.PI
| Named export | Default export | |
|---|---|---|
| How many per file | any number | one at most |
| Import | import { add } from './math' | import multiply from './math' |
| Name when importing | must match (or as) | your choice |
| Typically in React | helper functions, hooks, types | the file's component (e.g. Lesson.tsx) |
import { useState } from 'react' // no dot = a package from node_modulesimport { products } from '../course/fakeApi.en' // ./ and ../ = your own file, path relative to this oneimport './styles.css' // an import for its side effect (loads the styles)// The .js/.ts/.tsx extension is usually left out in Vite projects
// components/index.js – one entry point for the whole folderexport { Button } from './Button'export { Card } from './Card'// elsewhere then: import { Button, Card } from './components'// Dynamic import – loads the module only when it's needed (returns a Promise)const { heavyChart } = await import('./charts.js')
JSON is a text notation for data that looks almost like a JavaScript object. It's used everywhere data travels: between the server and the browser, into files, into localStorage.
const user = { name: 'Anna', age: 31, tags: ['admin'] }const text = JSON.stringify(user)// '{"name":"Anna","age":31,"tags":["admin"]}' – one long piece of TEXTJSON.stringify(user, null, 2) // nicely indented – for debuggingJSON.parse(text) // back to an object (a new object!)
Math.round(4.5) // 5Math.floor(4.9) // 4 – downMath.ceil(4.1) // 5 – upMath.trunc(-4.9) // -4 – cut off the decimal partMath.abs(-7) // 7Math.max(3, 8, 1) // 8Math.min(...[3, 8, 1]) // 1 – with an array via spreadMath.sqrt(16) // 42 ** 8 // 256 – power (formerly Math.pow)// A random whole number from min to max (inclusive)const randomInt = (min, max) => Math.floor(Math.random() * (max - min + 1)) + minrandomInt(1, 6) // a die// A random item of an arrayconst pick = (arr) => arr[Math.floor(Math.random() * arr.length)]// Limiting to a rangeconst clamp = (n, min, max) => Math.min(Math.max(n, min), max)clamp(150, 0, 100) // 100
const now = new Date() // nowconst d = new Date(2026, 9, 4) // October 4, 2026 – months count from 0! 😱const iso = new Date('2026-10-04') // from text in the ISO format (year-month-day)const fromMs = new Date(1_700_000_000_000) // from the number of milliseconds since 1 January 1970d.getFullYear() // 2026d.getMonth() // 9 – October (January = 0)d.getDate() // 4 – the day of the monthd.getDay() // 0–6 – the day of the week (Sunday = 0)d.getHours() // 0Date.now() // the current time in ms – quick measuring and unique numbersd.getTime() // this date in msd.toISOString() // the standard text for servers – in UTC, so it can show a different day than your local time
// The difference of two dates = the difference in millisecondsconst DAY = 24 * 60 * 60 * 1000const days = Math.round((new Date('2026-12-24') - new Date('2026-10-04')) / DAY) // 81// ComparisondateA < dateB // works (compares ms)dateA.getTime() === dateB.getTime() // equality – === on two Date objects is always false!// Adding days – setDate CHANGES the object, so make a copy firstconst tomorrow = new Date(today)tomorrow.setDate(tomorrow.getDate() + 1) // Date handles overflowing the end of the month itself
Formatting numbers and dates by hand (thousands separators, the decimal mark, the currency symbol, month names) is unnecessary. The browser can do it in every language:
const n = 1234567.891n.toLocaleString('en-US') // '1,234,567.891'n.toLocaleString('de-DE') // '1.234.567,891'new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(n)// '$1,234,567.89'new Intl.NumberFormat('en-US', { maximumFractionDigits: 1 }).format(3.14159) // '3.1'new Intl.NumberFormat('en-US', { style: 'percent' }).format(0.256) // '26%'const date = new Date(2026, 9, 4)date.toLocaleDateString('en-US') // '10/4/2026'date.toLocaleDateString('en-GB') // '04/10/2026'date.toLocaleDateString('en-US', { day: 'numeric', month: 'long' }) // 'October 4'date.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }) // '12:00 AM'new Intl.RelativeTimeFormat('en', { numeric: 'auto' }).format(-1, 'day') // 'yesterday'new Intl.ListFormat('en').format(['Anna', 'Peter', 'Eve']) // 'Anna, Peter, and Eve'
What you see: Fields for a number and a date. Below them, how the built-in methods and Intl format them.
Try it:
toFixed and toLocaleString('en-US'): the first gives no thousands separators, the second formats it for people.RelativeTimeFormat writes "yesterday" / "tomorrow".The takeaway: Format numbers and dates for people with Intl and toLocale… plus a locale. Building the text by hand is unnecessary and error-prone.
Loading the interactive part…
localStorage is a small store in the browser. Data in it survive reloading the page and even closing the browser. The course uses it to remember which challenges you've finished.
localStorage.setItem('theme', 'dark') // store (key, value)localStorage.getItem('theme') // 'dark'localStorage.getItem('doesNotExist') // nulllocalStorage.removeItem('theme') // delete// It can only store TEXT – objects via JSONconst settings = { theme: 'dark', fontSize: 16 }localStorage.setItem('settings', JSON.stringify(settings))const loaded = JSON.parse(localStorage.getItem('settings') ?? 'null')// ❌ Without JSONlocalStorage.setItem('settings', settings) // stores '[object Object]'
A class is a cake mould: it describes what every object you make with it (new) looks like and what it can do. In modern React you'll hardly meet them – components are written as functions. But they do turn up now and then (the error boundary in lesson React 10, libraries, older code), so you should recognise them.
class Counter {count = 0 // a property with a default valueconstructor(start) { // called on new Counter(…)this.count = start ?? 0 // this = the object being made right now}increment() { // a methodthis.count++return this.count}}const a = new Counter(10)a.increment() // 11a.count // 11class LimitedCounter extends Counter { // inheritance: everything from Counter + something extraincrement() {if (this.count >= 3) return this.countreturn super.increment() // call the parent class's version}}
Two functions that built-in JavaScript does for you: rounding up and turning a value into text.
Task is in the comments in the code below – at the top of the file and at the places marked TODO.
Loading the interactive part…
Seven helper functions you'll find in almost every project: formatting a price and a date, limiting to a range, a random number, moving a date and saving to localStorage. What exactly each one should return is in the comments in the code.
Task is in the comments in the code below – at the top of the file and at the places marked TODO.
Loading the interactive part…
{ }, the default without them. A path with ./ is your own file, without it a package.Math.floor(Math.random() * (max - min + 1)) + min.setDate changes the object.toLocale… with a locale format numbers, currencies and dates for any language.new, this, extends). In modern React you'll rarely meet them.