Hone

Lessons · JavaScript · Quick reference

JavaScript quick reference

153 topics, one line each, in the order Hone teaches them.

Hone is a place to practise programming. This sheet is the whole JavaScript track at a glance: every idea it covers, in the order they are taught, one line each. It is a map rather than a lesson. Read opens the full explanation of an idea; Practise gives you a question on it. Both are free, and reading needs no account at all.

Data structures and algorithms · Things in a line

linked listsA linked list is small objects, each holding a value and a reference to the next one, ending at null. There is no index and no length. Read: Objects that point at the next object · Practise linked lists
stacks and queuesAn array is already a stack: push and pop work at the end. For a queue, shift() takes from the front but moves every remaining item, so a real queue keeps a head index instead. Read: Last in first out, and first in first out · Practise stacks and queues
two pointersInstead of comparing every pair with two nested loops, put one index at each end and move them toward each other, deciding at each step which one to move. Read: Two fingers, one pass · Practise two pointers
the sliding windowKeep a start and an end over the same sequence. The end always moves forward; the start moves forward only when the window has broken a rule. Read: A window that grows and shrinks · Practise the sliding window

Data structures and algorithms · Things in a grid

grids (a list of lists)grid[row][col]. The outer array holds rows, so the first bracket picks a row and the second picks a cell in it. Read: A grid is an array of arrays · Practise grids (a list of lists)
loop inside a loopn items in the outer loop times n in the inner is n squared. 1,000 becomes a million. Read: A loop inside a loop multiplies · Practise loop inside a loop
scanning an array is slowWalk the array once and keep a single number about the past; that is often all you need. Read: One pass, one running fact · Practise scanning an array is slow

Data structures and algorithms · Things in a tree

binary treesA binary tree node holds a value and at most two children. In a binary SEARCH tree everything left is smaller and everything right is larger. Read: A node, a left and a right · Practise binary trees
walking a treeDepth-first goes all the way down one branch before the next, and recursion does it for free. Breadth-first goes level by level, and needs a queue. Read: Two ways to visit every node · Practise walking a tree
a function that calls itselfA function that calls itself on a smaller input, with a base case that stops it. Read: A problem defined by a smaller version of itself · Practise a function that calls itself

Data structures and algorithms · Things in an order

what sorting costssort() costs about n log n and is stable in modern JavaScript, so items that compare equal keep the order they had. By default it sorts as TEXT, so numbers need a comparator. Read: What sorting costs, and what it buys · Practise what sorting costs
heaps (the smallest first)A heap keeps only enough order to know its minimum, so push and pop each cost about log n. JavaScript has no heap in the standard library, so you write the two loops yourself. Read: Always hand me the smallest · Practise heaps (the smallest first)
sort with a comparatorThe comparator decides order: return negative, zero or positive. To sort by two fields, compare the first and fall through to the second. Read: Sort by the thing that matters · Practise sort with a comparator

Data structures and algorithms · Things joined to things

graphs (things joined to things)A graph is usually a Map, or a plain object, from each node to the list it joins. Unlike a tree it can hold cycles, so every walk needs a Set of what it has already seen. Read: Things joined to things · Practise graphs (things joined to things)
memoising (not doing it twice)When a recursion asks the same smaller question down more than one branch, store each answer the first time. The code barely changes; the cost changes class. Read: Remember what you already worked out · Practise memoising (not doing it twice)
greedy choicesA greedy algorithm makes the choice that looks best at each step and never reconsiders. That is why it is fast, and why it is sometimes wrong. Read: Take the best step now, and never look back · Practise greedy choices

JavaScript for the web · Values

typeoftypeof x returns a string naming the type: 'string', 'number', 'boolean', 'undefined', 'object', 'function'. Read: What kind of value is this · Practise typeof
+ with a string and a numberIf either side of + is a string, + joins: '5' + 1 is '51'. Every other arithmetic operator converts to numbers instead. Read: When + stops adding · Practise + with a string and a number
joining two strings+ between strings joins them, and a non-string on either side is turned into text first. A template literal, `Total: ${x}`, does the same more readably. Read: Joining text · Practise joining two strings
adding two numbersWith two numbers, + adds. The surprises come only when one side is a string, and from floating point, as in every language. Read: Plain addition · Practise adding two numbers
! flips true and false! turns true into false and false into true. Applied to a non-boolean it first converts the value to a boolean, which is why !0 is true. Read: Flipping a condition · Practise ! flips true and false
the one-line ifcondition ? whenTrue : whenFalse is an expression: it produces one of the two values, so it can sit inside an assignment or a template. Read: A one-line if that has a value · Practise the one-line if

JavaScript for the web · Arrays

pusharr.push(x) adds x to the end of the array in place and returns the new length. unshift adds to the front. Read: Adding to the end · Practise push
the first item is item 0arr[i] is the item at position i, counting from 0. Out of range gives undefined, not an error. Read: Picking an item by position · Practise the first item is item 0
length and the last item"hello".length is 5 and [1, 2, 3].length is 3. length counts items; the last index is length - 1. Read: How many · Practise length and the last item
filterarr.filter(fn) returns a new array of the items for which fn returned something truthy. The original is untouched. Read: Keeping what passes · Practise filter
join (pieces to text)arr.join(sep) makes one string with sep between the items. split does the reverse. Read: Gluing a list into text · Practise join (pieces to text)
slice copies, splice changesslice(start, end) returns a copy of part of the array; splice(start, count) removes items from the array itself. Read: slice copies, splice cuts · Practise slice copies, splice changes

JavaScript for the web · Truth and equality

what counts as trueOnly six values are falsy: false, 0, '', null, undefined and NaN. Everything else is truthy, including '0', 'false', [] and {}. Read: What counts as true · Practise what counts as true
why === and not ==== converts the two sides to a common type before comparing, by rules almost nobody remembers; === compares as they are. Read: Why === and not == · Practise why === and not ==
null vs undefined vs emptyx != null is true for every value except null and undefined. if (x) also rejects 0, '' and false, which is usually not what you meant. Read: Does it have a value · Practise null vs undefined vs empty
never set, or set to nothingundefined is the absence nobody chose: a variable never assigned, a missing property. null is an absence someone set on purpose. Read: Two kinds of nothing · Practise never set, or set to nothing
!! makes a boolean!!x converts any value to true or false by negating twice. It is the same conversion as Boolean(x). Read: Forcing a boolean · Practise !! makes a boolean
?? only catches null and undefineda ?? b gives b only when a is null or undefined. a || b gives b for every falsy a, including a real 0 or ''. Read: A default only for missing · Practise ?? only catches null and undefined

JavaScript for the web · Functions and scope

let is bounded by its blocklet and const are limited to the block they are declared in. var leaks out of its block, and reading a let before its line throws. Read: Where a variable lives · Practise let is bounded by its block
reading a name before it existsFunction declarations are hoisted whole, so you can call them above their definition. var is hoisted as undefined. let and const are hoisted but unusable before their line. Read: What exists before its line · Practise reading a name before it exists
functions that rememberA function keeps access to the variables around it when it was created, even after the outer function has returned. Read: A function that remembers where it was made · Practise functions that remember
arrow functions and thisAn arrow function has no this of its own; it uses the this of the code around it. A regular function gets its own this, set by how it is called. Read: Arrows keep the this they were born in · Practise arrow functions and this
default parametersfunction f(x = 5) uses 5 only when x is undefined: missing, or passed as undefined. null and 0 are real values and are kept. Read: A default when the argument is missing · Practise default parameters
... spread[...a] makes a new array with the same items; {...o} does the same for objects. The copy is one level deep: nested arrays and objects are shared. Read: Copying with three dots · Practise ... spread

JavaScript for the web · Async

async always hands back a promiseMarking a function async wraps its return value in a Promise. return 1 becomes a promise that resolves to 1, and a throw becomes a rejected promise. Read: An async function always returns a promise · Practise async always hands back a promise
catching a promiseA promise that rejects with nobody listening is an unhandled rejection: often silent, sometimes fatal. Attach .catch, or await inside try/catch. Read: Catching a rejection · Practise catching a promise
async / awaitawait inside an async function pauses that function until the promise settles. Everything outside it keeps running, which is the whole point. Read: await pauses only its own function · Practise async / await
the event loopCode already running finishes first. Then queued promise callbacks run, then timers. setTimeout(fn, 0) means 'after the current work', not 'now'. Read: What runs when · Practise the event loop

JavaScript for the web · Objects and classes

classes and newA class describes what a kind of thing has and does. new Dog('Rex') builds one Dog and runs its constructor on it. Read: A class builds objects with new · Practise classes and new
this in methodsInside a method, this is whatever the method was called on. Detach the method from its object and this is gone. Read: this is the object before the dot · Practise this in methods
extends and superclass Puppy extends Dog makes every Dog method work on a Puppy. super(...) runs the parent's constructor, and a method of the same name in the child overrides the parent's. Read: extends shares a parent; super reaches it · Practise extends and super
getters, static and #privateget area() computes a value that is read without parentheses. static square() belongs to the class itself, not to instances. #w is a field only the class body can touch. Read: Getters read like properties; static lives on the class · Practise getters, static and #private
prototypes under the hoodMethods written in a class body live once, on Dog.prototype; each object holds only its own fields and finds methods by walking the prototype chain. Read: A class is a prototype with nicer syntax · Practise prototypes under the hood

JavaScript for the web · Prove it works

assertnode's assert throws an AssertionError with your message when a claim fails and does nothing when it holds. It is a sentence about your code that the computer checks. Read: assert says what must be true · Practise assert
a test functionA test runner such as Jest or Vitest collects every test('name', fn) call, runs each, and reports the names that failed. Each test pins one fact down. Read: A test is a named function that asserts one fact · Practise a test function
arrange, act, assertSet up the inputs, call the one thing being tested, check the result. Three short steps in that order, so a test can be read at a glance. Read: Arrange, act, assert · Practise arrange, act, assert
edge cases firstMost bugs live at the edges: the empty array, the single item, all items equal, and the division that becomes 0 / 0. Test those first; the middle usually follows. Read: Test the ends first: nothing, one, everything the same · Practise edge cases first

More

some() and every()arr.some(fn) asks 'is at least one true?', arr.every(fn) asks 'are they all true?', in one line. Read: Asking a question of every item at once · Practise some() and every()
array.lengthQuestions on Hone; no lesson yet. Practise array.length
map, filter and friendsQuestions on Hone; no lesson yet. Practise map, filter and friends
storing a value in a nameconst name = value stores a value under a name so you can use it again; let is for names that will be reassigned. Read: Naming a value · Practise storing a value in a name
map and filtermap transforms each item; filter keeps some; chain them to do both, without a loop and a push. Read: Build a new array from an old one · Practise map and filter
const stops reassignment, not changeQuestions on Hone; no lesson yet. Practise const stops reassignment, not change
const binds the nameQuestions on Hone; no lesson yet. Practise const binds the name
reassigning a constconst means the variable cannot be pointed at something else; the object or array it points to can still change. Read: const fixes the name, not the contents · Practise reassigning a const
== vs ===Questions on Hone; no lesson yet. Practise == vs ===
template literalsA template literal `...${value}...` drops a value into a string where the braces are. Read: Putting values into text · Practise template literals
0.1 + 0.2Questions on Hone; no lesson yet. Practise 0.1 + 0.2
look it up in a MapWalk the data once; store each thing you see in a Map (or object) keyed by what you will later need to look up. Read: Remember what you have seen, in a Map · Practise look it up in a Map
is it in therearray.includes(x) and string.includes(sub) answer yes or no; indexOf gives the position or -1. Read: Is it in there? · Practise is it in there
Math.floor and %JavaScript has no integer division operator: use Math.floor(a / b) for the whole part and a % b for the remainder. Read: Whole parts and remainders in JavaScript · Practise Math.floor and %
Array(n).fill()Questions on Hone; no lesson yet. Practise Array(n).fill()
holes in arraysQuestions on Hone; no lesson yet. Practise holes in arrays
setting .length cuts it shortQuestions on Hone; no lesson yet. Practise setting .length cuts it short
[] + []Questions on Hone; no lesson yet. Practise [] + []
[] + {}Questions on Hone; no lesson yet. Practise [] + {}
two arrays are never ===Questions on Hone; no lesson yet. Practise two arrays are never ===
Boolean(0)Questions on Hone; no lesson yet. Practise Boolean(0)
filter then mapQuestions on Hone; no lesson yet. Practise filter then map
3 > 2 > 1Questions on Hone; no lesson yet. Practise 3 > 2 > 1
closuresQuestions on Hone; no lesson yet. Practise closures
"5" - 1 gives a numberQuestions on Hone; no lesson yet. Practise "5" - 1 gives a number
"5" + 1 gives textQuestions on Hone; no lesson yet. Practise "5" + 1 gives text
the comma operatorQuestions on Hone; no lesson yet. Practise the comma operator
concat() joins arraysQuestions on Hone; no lesson yet. Practise concat() joins arrays
const cannot be reassignedQuestions on Hone; no lesson yet. Practise const cannot be reassigned
destructuringQuestions on Hone; no lesson yet. Practise destructuring
1 / 0 is InfinityQuestions on Hone; no lesson yet. Practise 1 / 0 is Infinity
every()Questions on Hone; no lesson yet. Practise every()
find()Questions on Hone; no lesson yet. Practise find()
flat()Questions on Hone; no lesson yet. Practise flat()
0.1 + 0.2 is not 0.3Questions on Hone; no lesson yet. Practise 0.1 + 0.2 is not 0.3
var hoistingQuestions on Hone; no lesson yet. Practise var hoisting
includes() on an arrayQuestions on Hone; no lesson yet. Practise includes() on an array
indexOf()Questions on Hone; no lesson yet. Practise indexOf()
Array.isArray()Questions on Hone; no lesson yet. Practise Array.isArray()
Number.isInteger()Questions on Hone; no lesson yet. Practise Number.isInteger()
JSON.parseQuestions on Hone; no lesson yet. Practise JSON.parse
let is block scopedQuestions on Hone; no lesson yet. Practise let is block scoped
== and ===Questions on Hone; no lesson yet. Practise == and ===
map vs forEachQuestions on Hone; no lesson yet. Practise map vs forEach
Math.max() with nothingQuestions on Hone; no lesson yet. Practise Math.max() with nothing
Math.max(...arr)Questions on Hone; no lesson yet. Practise Math.max(...arr)
minus converts, plus joinsQuestions on Hone; no lesson yet. Practise minus converts, plus joins
10 % 3Questions on Hone; no lesson yet. Practise 10 % 3
changing a parameterQuestions on Hone; no lesson yet. Practise changing a parameter
NaNQuestions on Hone; no lesson yet. Practise NaN
null == undefinedQuestions on Hone; no lesson yet. Practise null == undefined
null === undefinedQuestions on Hone; no lesson yet. Practise null === undefined
Number("") is 0Questions on Hone; no lesson yet. Practise Number("") is 0
Number("abc") is NaNQuestions on Hone; no lesson yet. Practise Number("abc") is NaN
typeof 42Questions on Hone; no lesson yet. Practise typeof 42
object keys are stringsQuestions on Hone; no lesson yet. Practise object keys are strings
Object.values()Questions on Hone; no lesson yet. Practise Object.values()
?. optional chainingQuestions on Hone; no lesson yet. Practise ?. optional chaining
parseInt stops at the lettersQuestions on Hone; no lesson yet. Practise parseInt stops at the letters
parseInt with a baseQuestions on Hone; no lesson yet. Practise parseInt with a base
1 + {}Questions on Hone; no lesson yet. Practise 1 + {}
x++ hands back the old valueQuestions on Hone; no lesson yet. Practise x++ hands back the old value
reduceQuestions on Hone; no lesson yet. Practise reduce
reduce() to a totalQuestions on Hone; no lesson yet. Practise reduce() to a total
...rest when destructuringQuestions on Hone; no lesson yet. Practise ...rest when destructuring
|| and a defaultQuestions on Hone; no lesson yet. Practise || and a default
slice() on an arrayQuestions on Hone; no lesson yet. Practise slice() on an array
[10, 9, 1].sort((a, b) => a - b)Questions on Hone; no lesson yet. Practise [10, 9, 1].sort((a, b) => a - b)
sort() compares as textQuestions on Hone; no lesson yet. Practise sort() compares as text
sort() sorts as textQuestions on Hone; no lesson yet. Practise sort() sorts as text
'a,b,c'.split(',')Questions on Hone; no lesson yet. Practise 'a,b,c'.split(',')
[...a] copiesQuestions on Hone; no lesson yet. Practise [...a] copies
{...a, ...b}Questions on Hone; no lesson yet. Practise {...a, ...b}
includes() on textQuestions on Hone; no lesson yet. Practise includes() on text
strings cannot changeQuestions on Hone; no lesson yet. Practise strings cannot change
slice() on a stringQuestions on Hone; no lesson yet. Practise slice() on a string
template stringsQuestions on Hone; no lesson yet. Practise template strings
an empty array is truthyQuestions on Hone; no lesson yet. Practise an empty array is truthy
Boolean("")Questions on Hone; no lesson yet. Practise Boolean("")
Boolean("0")Questions on Hone; no lesson yet. Practise Boolean("0")
typeof a functionQuestions on Hone; no lesson yet. Practise typeof a function
typeof NaNQuestions on Hone; no lesson yet. Practise typeof NaN
typeof nullQuestions on Hone; no lesson yet. Practise typeof null
typeof Symbol()Questions on Hone; no lesson yet. Practise typeof Symbol()
typeof undefinedQuestions on Hone; no lesson yet. Practise typeof undefined
toUpperCase()Questions on Hone; no lesson yet. Practise toUpperCase()
array or Map?An array is for things in order, reached by position; an object or Map is for things with a name, reached by key. Read: Array or object? · Practise array or Map?
copy before you change itObjects and arrays are passed by reference: changing one inside a function changes the caller's copy too. Read: Changing what was handed to you · Practise copy before you change it
object keys are textWhatever you use as a key on a plain object becomes a string. Numbers work by accident; objects collapse to '[object Object]'. Read: Object keys are strings · Practise object keys are text
counting loopsfor (let i = 0; i < n; i++) counts from 0 up to but not including n. Read: Counting with a loop · Practise counting loops
folding a list into one valuereduce walks the array carrying an accumulator; each step returns the new accumulator. Start it with an initial value. Read: Fold a list into one value · Practise folding a list into one value
leave as soon as you knowreturn ends the function immediately; handle the simple cases first and the main path stays unindented. Read: Leave as soon as you know · Practise leave as soon as you know
Set removes duplicatesA Set holds each value once and answers has() instantly. Read: A collection that refuses duplicates · Practise Set removes duplicates
slice()slice(start, end) takes items from start up to but not including end; negative numbers count from the end. Read: A window onto an array or string · Practise slice()
sorting numbers as textWithout a comparator, sort converts everything to strings: [10, 9, 1] becomes [1, 10, 9]. Read: sort() sorts as text · Practise sorting numbers as text
searching sorted dataIn a sorted array look at the middle; the target is there, left, or right. Discard half each time. Read: Halve the search space each step · Practise searching sorted data
memory for speedPrecompute once into a table, then read from it, instead of recomputing in a loop. Read: Spend memory to save time · Practise memory for speed
cleaning and reshaping texttrim, toLowerCase, split, replace, startsWith return new strings; the original never changes. Read: Cleaning and reshaping text · Practise cleaning and reshaping text
while loopswhile (condition) repeats as long as the condition holds; use it when you do not know how many times in advance. Read: Repeat until something changes · Practise while loops
zip (walk two lists)Loop by index and read both arrays at position i, or map one array using the index to reach into the other. Read: Walking two arrays together · Practise zip (walk two lists)