Recap

JavaScript Fundamentals

Every lesson in a few lines, with the answer you'd give in an interview. About a 8-minute read.
Go to the course
Lesson 01

let, const and var

  • let can be assigned again. const can't. An array or object held in a const can still change inside.
  • Code reads variables in its own scope and the scopes around it. let and const live in their block. var lives in the whole function, and a top-level var becomes a property of window.
  • Every variable is created before its scope runs. A var starts as undefined, and reading a let or const before its line throws. Declaring a let or const twice is a SyntaxError. var allows it silently.
In an interview
What's the difference between var, let and const?
var belongs to the whole function, or to the global scope outside a function, where it also becomes a property of window. It ignores blocks, it can be declared twice without an error, and before its line runs it already holds undefined. let and const belong to the block they're written in. Declaring one twice is a SyntaxError, and reading one before its line throws a ReferenceError. That stretch of code is called the temporal dead zone. let can be assigned again. const can't, but an object or array it holds can still change inside. I use const by default, let when the value changes, and no var.
Lesson 02

The eight types

  • JavaScript has eight types. Seven are primitives: number, bigint, string, boolean, undefined, null and symbol. The eighth is object.
  • Arrays and functions are objects. typeof says "object" for an array and "function" for a function. Use Array.isArray to check for an array.
  • typeof null is "object", a bug kept so old sites still work. Check for null with === null.
In an interview
What are the data types in JavaScript?
There are eight. Seven are primitives: number, bigint, string, boolean, undefined, null and symbol. A primitive is one value. It has no properties of its own, and it can't change. The eighth is object, which includes arrays and functions. typeof returns the type as a string, with two surprises. typeof null is "object", a bug from the first version that was kept so old sites still work. typeof a function is "function", even though functions are objects. To check for an array, I use Array.isArray. A variable has no type of its own: a let can hold a number now and a string later.
Lesson 03

Type conversion

  • + joins strings when either side is a string. -, * and / convert both sides to numbers.
  • To a number: "" and null become 0. undefined and a string that isn't a number become NaN.
  • Eight values are falsy: false, 0, -0, 0n, "", null, undefined and NaN. Everything else is truthy, including "0", "false" and [].
In an interview
What is type coercion in JavaScript?
Coercion is JavaScript converting a value to another type for you, when an operator or a condition needs it. + joins strings when either side is a string, so "5" + 1 is "51". The other math operators convert values to numbers, so "5" - 1 is 4. Conditions convert values to booleans. Only eight values are falsy: false, 0, -0, 0n, the empty string, null, undefined and NaN. Everything else is truthy, including "0", "false" and an empty array. To avoid surprises, I convert on purpose with Number, String or Boolean. That matters most for values from inputs, the URL and localStorage, which are always strings.
Lesson 04

Comparing values: == and ===

  • === is true only when the type and the value match. == converts types first, by rules that are hard to remember.
  • null == undefined is true, and neither is loosely equal to anything else. NaN isn't equal to anything, itself included: use Number.isNaN.
  • Two strings compare character by character, so "9:00" < "10:00" is false. Two objects are equal only when they're the same object.
In an interview
What's the difference between == and ===?
=== is strict equality. It's true only when both values have the same type and the same value. It never converts. == is loose equality. When the types differ, it converts first. With a number and a string, the string becomes a number, so 10 == "10" is true. null and undefined are loosely equal to each other and to nothing else. NaN isn't equal to anything, so I check it with Number.isNaN. Objects are equal only when both sides are the same object. I use === everywhere, except value == null, which checks for null and undefined at once.
Lesson 05

Conditionals and loops

  • if and else pick one path. else if checks conditions in order and stops at the first true one. The ternary picks one of two values.
  • switch compares with ===, so the string "90" never matches case 90. Each case needs a break, or the next case runs too.
  • for...of loops over the values of an array. for...in loops over its keys, as strings. continue skips to the next pass, and break ends the loop.
In an interview
What's the difference between for...of and for...in?
for...of loops over the values of an iterable: an array, a string, a Map or a Set. for...in loops over the property names of an object, as strings. On an array, for...in gives the indexes "0", "1" and so on, and it also visits any extra properties added to the array, so I use for...of for arrays. To loop over a plain object, I use for...of with Object.entries.
Lesson 06

||, &&, ?? and ?.

  • || returns the first truthy value. && returns the first falsy value. Each returns the last value when it doesn't find one, and each stops once it has its answer.
  • ?? returns the right side only when the left side is null or undefined. Use it for defaults where 0, "" or false are real values.
  • ?. stops and gives undefined when the value on its left is null or undefined, instead of throwing.
In an interview
What's the difference between || and ?? for default values?
|| returns the right side when the left side is falsy, so it replaces 0, the empty string and false, as well as null and undefined. ?? returns the right side only when the left side is null or undefined. So when 0 is a real value, like a reminder 0 minutes before the start, remindBefore || 15 gives 15 by mistake, but remindBefore ?? 15 keeps 0. I use ?? for defaults, and || only when every falsy value means missing.
Lesson 07

Functions: declarations, expressions and arrows

  • A function declaration is hoisted with its body, so you can call it before its line. A function expression follows the rules of the variable that holds it.
  • An arrow with no braces returns its expression. To return an object, wrap it in parentheses. A missing argument is undefined, and a default replaces only undefined.
  • A function reads outside variables when it runs. Functions made in a var loop share one variable. A let loop gives each pass its own.
In an interview
What's the difference between a function declaration, a function expression and an arrow function?
A declaration starts with the function keyword as a statement. It's hoisted with its body, so you can call it anywhere in its scope, even above its line. A function expression is a function used as a value, usually assigned to a variable. It follows that variable's rules, so with const it's in the temporal dead zone until its line. An arrow function is a shorter expression. With no braces, it returns its expression. All three are closures: they read outside variables when they run, not when they're made. So functions made in a var loop all see the last value, and a let loop gives each one its own.
Lesson 08

Arrays: the basics

  • An array keeps values in order, from index 0. length is the number of items. at(-1) reads the last one, but [-1] is undefined.
  • push and pop work at the end, unshift and shift at the start. splice(start, count) removes from the middle. All of them change the array.
  • indexOf gives an index, or -1, and includes gives true or false. forEach, map and filter call a function with each item, then its index. map and filter return a new array.
In an interview
How do you add and remove items in a JavaScript array?
At the end, push adds and pop removes. At the start, unshift adds and shift removes. To remove from the middle, I find the position with indexOf and call splice(position, 1). Without the count, splice removes everything to the end. All of these change the array in place. When I need a new array instead, I use map to change every item or filter to keep some, and both leave the original alone. To check whether a value is in the array, I use includes, because indexOf returns 0 for the first item, which is falsy, and -1 for a missing one, which is truthy.
Lesson 09

Objects: the basics

  • An object keeps values under names, called properties. Use a dot for a name you know, and brackets for a name held in a variable.
  • Assigning adds or changes a property, and delete removes one. A missing property reads as undefined. in tells missing apart from set to undefined.
  • Objects and arrays can nest. Object.keys and Object.values give arrays. Object.entries gives [key, value] pairs to loop over with for...of, and for...in gives the keys.
In an interview
How do you read and loop over an object's properties?
A dot reads a property whose name I know when I write the code, like booking.minutes. Brackets read a name held in a variable, like booking[field]. Reading a property that isn't there gives undefined, so to tell a missing property from one set to undefined, I use the in operator. To loop, for...in gives the keys, and Object.entries gives [key, value] pairs that I loop over with for...of. Object.keys and Object.values give just the keys or just the values.