JavaScript at Breakneck Speed

The Super-Fast JavaScript Refresher Drills

George Marklow
14 min readJul 17, 2022
Photo by Steve Johnson on Unsplash

Introduction

Cramming for an upcoming interview or coming back to front-end work after a long spell elsewhere?

You’ve come to the right place!

Each section of this article consists of a ‘drill’ that explores frequently-used JavaScript operations, as well as interesting nuiances of the language.

Names of variables and methods are kept deliberately short to minimize the amount of typing required to complete the code exercises.

What This Article Is Not

This article is about learning by doing and doesn’t offer thorough explanations of the operations used. You’re left to explore these operations in more detail on your own.

Setup

Browser

In Google Chrome, open the Developer Tools and run JavaScript directly in the console:

Repl

Here, I’ve created a Node.js environment with no need to install anything. You can either type your code on the left-hand side and run it, or execute it directly from the terminal on the right-hand side.

I’ve created a method ‘o’ that saves the need to write console.log(…) repeatedly:

Download and Install Node.js

If you prefer to work with your local environment, install Node.js :

Next, open the terminal, type ‘node’, and hit ENTER. Then, execute your JavaScript code. Executing JavaScript this way is much faster for exploring fundamental operations since printing to the console is taken care of:

If you prefer to work with files in an IDE, use an editor such as VS Code :

Code Results

I display the expected output on the right-hand side with a comment. For example:

Number.isInteger(1) // true

For operations that throw exceptions, I use the 🔥 emoji. For example:

Math.PI.toPrecision(0) // 🔥

Let’s get started!

Strings

Throughout this drill, we’ll be using the following constant strings:

const s = ‘Abc’
const t = ‘ def ‘

Case and Length

s                // ‘Abc’
s.toLowerCase() // ‘abc’
s.toUpperCase() // ‘ABC’
s.length // 3

Extract Characters

s[0]                    // ‘A’
s[s.length 1] // ‘c’
s[3] // undefined
s[-1] // undefined
s.substring(0,2) // ‘Ab’
s.substring(2) // ‘c’
s.substring(3) // ‘’
s.substring(-1) // ‘Abc’
s.substring(-3) // ‘Abc’

Concatenation and Interpolation

s + t       // ‘Abc def ‘
`s: ${s}` // ‘s: Abc’
`s: ${s}
t: ${t}` // ‘s: Abc
// t: def ‘

Remove Whitespace

t.trimStart() // ‘def ‘
t.trimEnd() // ‘ def’
t.trim() // ‘def’

Check the Start and End Characters of String

s.startsWith(‘A’) // true
s.startsWith(‘a’) // false
s.endsWith(‘c’) // true
s.endsWith(‘x’) // false

Extracting Parts of Strings

s.slice(0)        // ‘Abc’
s.slice(1) // ‘bc’
s.slice(2) // ‘c’
s.slice(3) // ‘’
s.slice(0,1) // ‘A’
s.slice(0,2) // ‘Ab’
s.slice(1,2) // ‘b’
s.slice(1,3) // ‘bc’
s.slice(1,4) // ‘bc’
s.slice(-1) // ‘c’
s.slice(-2) // ‘bc’
s.slice(-3) // ‘Abc’
s.slice(-2,-1) // ‘b’
s.slice(-3,-2) // ‘A’
s.slice(-3,-1) // ‘Ab’
s.slice(2,1) // ‘’
s.slice(-2,-3) // ‘’

Stringify

String(true)      // ‘true’
String(null) // ‘null’
String(undefined) // ‘undefined’

Compare Strings

‘1’ < ‘2’ // true
‘2’ < ‘1’ // false
‘a’ < ‘b’ // true
‘b’ < ‘a’ // false
‘A’ < ‘b’ // true
‘a’ < ‘B’ // false
‘A’ < ‘B’ // true

Includes

s.includes(‘A’) // true
s.includes(‘a’) // false

Finding the Index

s.indexOf(‘A’)     // 0
s.indexOf(‘a’) // 1
s.match(/A/g) // [‘A’]
s.match(/a/g) // null
const u = s.repeat(2)u.indexOf(‘A’) // 0
u.lastIndexOf(‘A’) // 3
u.indexOf(‘A’, 0) // 0
u.indexOf(‘A’, 1) // 3
u.indexOf(‘A’, 2) // 3
u.indexOf(‘A’, 3) // 3
u.indexOf(‘A’, 4) // 0
u.match(/A/g) // [‘A’,’A’]

Numbers

Drill Throughout this drill, we’ll be using the following constant numbers and strings:

const a = 2
const b = ‘3’
const c = Math.PI
const d = 123.456

Arithmetic

a + 3     // 5
a 3 // 1
a * 2 // 4
a * 1.25 // 2.5
a / 2 // 1
a / 3 // 0.6666666666666666
a % 2 // 0
a % 3 // 2
a ** 2 // 4
a ** 1.5 // 2.82842712474619

Number to String

d.toString()         // ‘123.456’
`d: ${d}` // ‘d: 123.456’
null.toString() // 🔥
undefined.toString() // 🔥

String to Number

Number.parseInt(a)           // 2
Number.parseInt(d) // 123
Number.parseInt(a, 10) // 2
Number.parseInt(null) // NaN
Number.parseInt(undefined) // NaN
Number.parseFloat(a) // 2
Number.parseFloat(d) // 123.456
Number.parseFloat(null) // NaN
Number.parseFloat(undefined) // NaN

String Concatenation Instead of Arithmetic Operation

a + b           // ‘23’
a + parseInt(b) // 5

Convert Number to String and Round by Decimal Places

c.toFixed()          // ‘3’
c.toFixed(0) // ‘3’
c.toFixed(1) // ‘3.1’
c.toFixed(2) // ‘3.14’
c.toFixed(3) // ‘3.142’
d.toFixed() // ‘123’
d.toFixed(0) // ‘123’
d.toFixed(1) // ‘123.5’
d.toFixed(2) // ‘123.46’
d.toFixed(3) // ‘123.456’
d.toFixed(null) // ‘123’
d.toFixed(undefined) // ‘123’
d.toFixed(-1) // 🔥

Convert Number to String and Round by Significant Figures

a.toPrecision(1)         // ‘2’
a.toPrecision(4) // ‘2.000’
c.toPrecision() // ‘3.141592653589793’
c.toPrecision(0) // 🔥
c.toPrecision(1) // ‘3’
c.toPrecision(2) // ‘3.1’
c.toPrecision(3) // ‘3.14’
d.toPrecision() // ‘123.456’
d.toPrecision(0) // 🔥
d.toPrecision(1) // ‘1e+2’
d.toPrecision(2) // ‘1.2e+2’
d.toPrecision(3) // ‘123’
d.toPrecision(undefined) // ‘123.456’
d.toPrecision(null) // 🔥
d.toPrecision(-1) // 🔥

Exponentials

c.toExponential(0)         // ‘3e+0’
c.toExponential(1) // ‘3.1e+0’
c.toExponential(2) // ‘3.14e+0’
d.toExponential(0) // ‘1e+2’
d.toExponential(1) // ‘1.2e+2’
d.toExponential(2) // ‘1.23e+2’
d.toExponential(null) // ‘1e+2’
d.toExponential(undefined) // ‘1.23456e+2’
d.toExponential(-1) // 🔥

Round, Ceil, and Floor

Math.round(c)         // 3
Math.floor(c) // 3
Math.ceil(c) // 4
Math.round(‘’) // 0
Math.round(‘2.5’) // 3
Math.round(‘a’) // NaN
Math.round(null) // 0
Math.floor(null) // 0
Math.ceil(null) // 0
Math.round(undefined) // NaN

Convert Number to String and Round by Significant Figures

a.toPrecision(1)           // ‘2’
a.toPrecision(4) // ‘2.000’
c.toPrecision() // ‘3.141592653589793’
c.toPrecision(0) // 🔥
c.toPrecision(1) // ‘3’
c.toPrecision(2) // ‘3.1’
c.toPrecision(3) // ‘3.14’
d.toPrecision() // ‘123.456’
d.toPrecision(0) // 🔥
d.toPrecision(1) // ‘1e+2’
d.toPrecision(2) // ‘1.2e+2’
d.toPrecision(3) // ‘123’
d.toPrecision(undefined) // ‘123.456’
d.toPrecision(null) // 🔥
d.toPrecision(-1) // 🔥 Exponentials
c.toExponential(0) // ‘3e+0’
c.toExponential(1) // ‘3.1e+0’
c.toExponential(2) // ‘3.14e+0’
d.toExponential(0) // ‘1e+2’
d.toExponential(1) // ‘1.2e+2’
d.toExponential(2) // ‘1.23e+2’
d.toExponential(null) // ‘1e+2’
d.toExponential(undefined) // ‘1.23456e+2’
d.toExponential(-1) // 🔥

Round, Ceil, and Floor

Math.round(c)         // 3
Math.floor(c) // 3
Math.ceil(c) // 4
Math.round(‘’) // 0
Math.round(‘2.5’) // 3
Math.round(‘a’) // NaN
Math.round(null) // 0
Math.floor(null) // 0
Math.ceil(null) // 0
Math.round(undefined) // NaN
Math.floor(undefined) // NaN
Math.ceil(undefined) // NaN

The Number Class

Number(true)       // 1
Number(false) // 0
Number(null) // 0
Number(undefined) // NaN
Number(b) // 3
Number(d) // 123.456
Number(` ${a} `) // 2
Number(‘1,2’) // NaN
Number(‘1 2’) // NaN
Number(‘a’) // NaN

Checking a Number is an Integer

Number.isInteger(1)         // true
Number.isInteger(2.5) // false
Number.isInteger(‘1’) // false
Number.isInteger(null) // false
Number.isInteger(undefined) // false

Large and Small Numbers

Number.MAX_VALUE         // 1.7976931348623157e+308
Number.MIN_VALUE // 5e-324
Number.POSITIVE_INFINITY // Infinity
1/0 // Infinity
Number.NEGATIVE_INFINITY // Infinity
1/0 // Infinity

Boolean

Standard vs. Strict Equality

2 == '2'                     // true
2 === '2' // false

'' == 0 // true
'' === 0 // false

1 == true // true
1 === true // false
0 == false // true
0 === false // false

null == undefined // true
null === undefined // false

Object Reference Equality

class Book {
constructor(title) {
this.title = title
}
}

const book1 = new Book('Drills in JavaScript')
const book2 = new Book('Drills in JavaScript')

book1 == book1 // true
book1 === book1 // true
book1 == book2 // false
book1 === book2 // false

const book3 = book1
book1 == book3 // true
book1 === book3 // true

String to Boolean

Boolean('test')              // true
Boolean('true') // true
Boolean('false') // true
Boolean('') // false

Number to Boolean

Boolean(2)                   // true
Boolean(0) // false
Boolean(-1) // true

Array to Boolean

Boolean(['a'])               // true
Boolean([]) // true

Object to Boolean

Boolean({})                  // true
Boolean(null) // false
Boolean(undefined) // false

Recap of Truthy & Falsy

const j = (x) => x ? true : falsej(1);                         // true
j([]); // true
j('1'); // true
j(true); // true
j({}); // true
j(0) // false
j(NaN) // false
j('') // false
j(false) // false
j(null) // false
j(undefined) // false

Functions

In this drill, we explore Javascript functions and cover control-flow, iteration basics, switch statements, and handling errors, with several examples given below.

Arithmetic

let a = (x,y) => { return x + y }
let b = (x,y) => { return x - y }
let c = (x,y) => { return x * y }
let d = (x,y) => { return x / y }
a(2,3) // 5
b(2,3) // -1
c(2,3) // 6
d(2,3) // 0.6666666666666666

Summation with forEach

const n = [1,2,3]
let x = 0
n.forEach(function(y){
x += y
})
x // 6

Control Flow Basics

const f = x => {
if (x === 2) {
return 'a'
} else if (x === 1) {
return 'b'
} else {
return 'c'
}
}
f(2) // 'a'
f(1) // 'b'
f(0) // 'c'

Control Flow with Switch

function f(x) {
switch(x) {
case 1:
return 'a'
case 0:
return 'b'
default:
return 'c'
}
}
f(1) // 'a'
f(0) // 'b'
f(-1) // 'c'

Switch with Multiple Values to Check

function f(x,y) {
switch(true) {
case x * y > 4:
return 'a'
break
case x * y > 2:
return 'b'
break
default:
return 'c'
}
}
f(2,3) // 'a'
f(2,2) // 'b'
f(1,0) // 'c'

Checking for Null Parameters

function f(x,y) {
if (y) {
console.log(`x: ${x}, y: ${y}`)
} else {
console.log(`x: ${x}`)
}
}
f('a','b') // 'x: a, y: b'
f('a') // 'x: a'

Arrow Functions

let f = x => x >= 0
f(3) // true
f(-1) // false
let g = (x,y) => x / y
g(8,2) // 4
g(1,3) // 0.3333333333333333

Terinary Operator

const f = x => (x < 10) ? true : falsef(5)                          // true
f(15) // false

Try-Catch on Code Block

function f() {
try {
throw 'e'
} catch (e) {
console.log(e)
}
}
f() // 'e'

Simulating a Function Call that Sometimes Fails

const f = (x) => {
try {
g()
}
catch(e) {
console.log(`${x} failed: ${e}`)
}
}
function g() {
var x = Math.random() <= 0.1
if (x) {
throw 'error'
}
}
for (let i = 0; i < 10; i++) {
f(i);
}
// 2 failed: error
// 8 failed: error

Stringify

function f() { return true }String(f) // 'function f() { return true }'

Arrays

In this drill, we’ll cover iterating through and manipulating array values and some valuable methods to perform filtering operations and check conditions are satisfied. We’ll also use Javascript’s spread operator to combine two arrays, split strings into arrays, and merge array elements into strings.

Let’s begin by defining variables we’ll revisit throughout this drill to memorize array operations:

const m = ['a','b','c','d']
const n = [1,2,3]
const s = 'A;b;c'

Access the Array

m                            // ['a','b','c','d']
m.length // 4
m[0] // 'a'
m[1] // 'b'
m[4] // undefined
m[m.length - 1] // 'd'
m[m.length - 2] // 'c'

Remove Items

m.pop()                      // 'd'
m // ['a','b','c']
m.splice(2,99) // ['c']
m // ['a','b']
m.shift() // 'a'
m // ['b']

Add Items

m.push('e')                  // 2
m // ['b','e']
m.unshift('g','h') // 4
m // ['g','h','b','e']

Clear the Array

m.length = 0
m // []

The Spread Operator

const f = (x) => [...x]f('c')                       // ['c']
f('ab') // ['a','b']

Deconstructing an Array

const y = ['a', 1]
const [a, b] = y
a // 'a'
b // 1

Merge Arrays with the Spread Operator

const a = ['a']
const b = ['b']
const c = [...'ab']
[...a, ...b] // ['a','b']
c // ['a','b']

Find the Average Number using ForEach

function f(m){
let x = 0
m.forEach(y => {
x += y
})
return Math.round(x / m.length)
}
f([1,2,3]) // 2

Find Index of an Entry

const f = (x) => x === 2
const g = (x) => x === 5
n.findIndex(f) // 1
n.findIndex(g) // -1

Filter Entries

n.filter(x => x > 1)         // [2,3]
n.filter(x => x < 1) // []

Find a Matching Entry

n.find(x => x === 1)         // 1
n.find(x => x === 0) // undefined
n.find(x => x > 0) // 1
n.find(x => x > 1) // 2

Reverse Elements

n.reverse()                  // [3,2,1]

Check if Conditions Satisfied

n.every(x => x > 0)          // true
n.every(x => x > 1) // false
n.includes(1) // true
n.includes(4) // false

Create an Array from Variable Number of Arguments

Array.of(1)                  // [1] 
Array.of(1,2,3) // [1,2,3]

Split String into Array

'a,b,c'.split(',')           // ['a','b','c']
'a,b,c'.split('.') // ['a,b,c']

Map

const t = s.split(';')           
t.map(x => x.toUpperCase()) // ['A','B','C']
t.map(x => x.toLowerCase()) // ['a','b','c']

Reduce

const m = [2, 4, 2]
m.reduce((x, y) => x * y, 2) // 32

Joining Array Elements Into a String

n.join('|') // 1|2|3

Concatenation with forEach

const f = x => {
let s = ''
x.forEach((y) => {
s += `${y} `
})
return s
}
f([1,2,3]) // '1 2 3'

Stringify Arrays

String(n)                    // '1,2,3'
String([['a','b'],n]) // 'a,b,1,2,3'

Math Library

The JavaScript built-in Math object contains constants and methods that allow you to carry out numerical operations. All properties and methods are static.

Truncating Numbers

const trunc = (x) => Math.trunc(x)trunc(1)                     // 1
trunc(Math.PI) // 3

Round, Ceil, and Floor

Math.round(1.4)              // 1
Math.round(1.5) // 2
Math.floor(1.9) // 1
Math.ceil(1.1) // 2
Math.round(null) // 0
Math.floor(null) // 0
Math.ceil(null) // 0

Powers, Roots, and Absolute Value

const abs = (x) => Math.abs(x)
const pow = (x,y) => Math.pow(x,y)
const sqrt = (x) => Math.sqrt(x)
const cbrt = (x) => Math.cbrt(x)

Working with Math Static Properties

const {PI} = Math
const pow = (x,y) => Math.pow(x,y)
const area = (r) =>
(4 * PI * pow(r,2))
.toFixed(2)
area(5) // '314.16'

Maximum and Minimum

const a = [-1,1,2]Math.min(...a)               // -1
Math.max(...a) // 2
Math.min(-1,1,2) // -1
Math.max(-1,1,2) // 2

Sign

const s = (x) => Math.sign(x)s(2)                         // 1
s(-2) // -1

Exponential and Logarithm

const exp = (x) => Math.exp(x)
const log = (x) => Math.log(x)
const log10 = (x) => Math.log10(x)
const log2 = (x) => Math.log2(x)
exp(1) // 2.718281828459045
log(Math.E) // 1
log10(10) // 1
log2(4) // 2

Random

const rand = () => Math.random() 
const ceil = (x) => Math.ceil(x)
const tossCoin = () => ceil(rand() * 2)
let heads = 0, tails = 0
for (let i = 0; i < 100; i++) {
const result = tossCoin()
if (result === 1) heads++
if (result === 2) tails++
}
console.log(heads) // 52
console.log(tails) // 48

JSON

We can move convert from a Javascript object to JSON with the stringify method, and in the other direction using the parse method.

Convert JSON string to Javascript object

const x = JSON.parse(
"\{\"a\":\"1\",\"b\":\"2\",\"c\":{\"d\":\"3\"}}")
x.a // '1'
x.b // '2'
x.c.d // '3'

Convert Javascript object to JSON string

const x = {
a: "1",
b: "2",
c: {
d: "3"
}
}
JSON.stringify(x) // '{"a":"1","b":"2","c":{"d":"3"}}'

Iterating

const f = x => {
let s = ""
x.forEach((y) => {
s += `${y.a}:${y.b};`
})
return s;
}
const x = { a:"1", b:"2" }
const y = { a:"3", b:"4" }
f([x,y]) // '1:2;3:4;'

Classes and Objects

Throughout this drill, we’ll be re-using the following class, function and constant:

class A {
constructor(x,y) {
this.x = x
this.y = y
this.m = []
}

get p() {
return (this.x * this.y) > 10
}
get q() {
return `x: ${this.x}, y: ${this.y}`
}
r(x) {
this.m.push(x)
}

s(x) {
return this.m.includes(x)
}
}
function B(x,y) {
this.x = x
this.y = y
}
const c = {
p: 'a',
q: {
r: 1,
s: 2
}
}

Checking for Equality

1 == '1';                     // true
1 == [1]; // true
'1' == [1]; // true
1 === '1'; // false
1 === [1]; // false
'1' === [1]; // false

Accessing Values

c.p;                         // 'a'
c.q.r; // 1
c.q.s; // 2
Object.keys(c); // [ 'p','q' ]
Object.values(c); // ['a',{ r: 1,s: 2 }]
c['p']; // 'a'
c['q']; // { r: 1, s: 2 }
c['q']['r'] // 1
c['q']['s'] // 2

Combining Objects

const d = {
q: 'c'
};
console.log({ ...c, ...d }) // { p: 'a', q: 'c' }

Destructing Objects

const { p, q, r ='r' } = c;p;                           // 'a'
q; // { r: 1, s: 2 }
r; // 'r'

Class Instances

const a1 = new A(1,2)
const a2 = new A(3,4)
a1.x // 1
a1.y // 2
a2.x // 3
a2.y // 4
a1.p // false
a2.p // true
a1.q // x: 1, y: 2
a2.q // x: 3, y: 4
a1.s(1) // true
a1.s(3) // false

Inheritance

B.prototype.r = function() {
return `x: ${this.x}, y: ${this.y}`
}
b = new B(1,2)
b.r() // x: 1, y: 2
class E extends B {
r() { return 'r'; };
s() { return 3; };
}
const e = new E();
e.r() // 'r'
e.s() // 3

Setting Object Properties

const f = (x) => {
x.find(z => z.a === 2).b = true
return x
}
const x = [{
a: 1,
b: true
}, {
a: 2,
b: false
}]
f(x) // [
// { a: 1, b: true },
// { a: 2, b: true }
// ]

Printing Object Property Values

const f = (x) => {
let s = x.map(z => z.a)
return s.join(' ')
}
const x = [{
a: 1,
b: true
}, {
a: 2,
b: false
}]
f(x) // '1 2'const h = (x, z) => {
const y = {
"a": `1 ${x}`,
"b": `2 ${x}`
}
return y[z.p]
}
const a = {
p: 'a'
}
const b = {
p: 'b'
}
h('a', a) // '1 a'
h('b', b) // '2 b'
const i = x => {
const y = {
1: "a",
2: "b"
}
return y[x] || 'error'
}
i(1) // 'a'
i(2) // 'b'
i(3) // 'error'
const array = []typeof array === 'object' // true
array.constructor === Array // true
Object.prototype.toString.apply(array)
=== '[object Array]' // true

Not a Number

typeof NaN === 'number'       // true
NaN === NaN // false
NaN !== NaN // true
isNaN(NaN) // true

Sorting and Array of Objects

const m = [
{ 'a': 't', 'b': 2 },
{ 'a': 'r', 'b': 1 },
{ 'a': 's', 'b': 3 }
]
const k = function(x) {
return function(y, z) {
if (!y
|| !z
|| typeof y !== 'object'
|| typeof z !== 'object') return
const a = y[x], b = z[x]
if (a === b) return 0
if (typeof a === typeof b) return a < b ? -1 : 1
return typeof a < typeof b ? -1 : 1
}
}
m.sort(k('a')) // [
// { a: 'r', b: 1 },
// { a: 's', b: 3 },
// { a: 't', b: 2 }
// ]
m.sort(k('b')) // [
// { a: 'r', b: 1 },
// { a: 't', b: 2 },
// { a: 's', b: 3 }
// ]

Checking Object Contains a Property

const x = { a: 1 }
const y = Object.create(x)
x.hasOwnProperty('a') // true
y.hasOwnProperty('a') // false
x.a // 1
y.a // 1

Thanks for reading! Let me know what you think in the comments section below, and don’t forget to subscribe 👍

--

--

George Marklow
George Marklow

Written by George Marklow

George is a software engineer, author, blogger, and abstract artist who believes in helping others to make us happier and healthier.

No responses yet