The Ultimate JavaScript Cheat Sheet for Beginners and Experienced Developers Alike

JavaScript is a powerful programming language that is widely used for developing web applications.

As widely used as it is, it is also complex, and it can quickly become overwhelming to keep track of all the concepts, functions, methods, and more.

This ultimate JavaScript cheat sheet covers everything from functions and arrays to classes, promises, and even scope.

It serves as a reference as well as a quick guide, as you'll find basic explanations for each one. Have fun exploring.

Table of Contents

  1. Basics
  2. Conditionals
  3. Functions
  4. Scope
  5. Arrays
  6. Loops
  7. Iterators
  8. Objects
  9. Classes
  10. Modules
  11. Promises
  12. Async Await
  13. Requests

Basics

Comments

Comments are used to add explanations or notes to the code. They are ignored by the computer when the code is executed, but are helpful for other developers who might be reading the code later. In JavaScript, there are two ways to add comments:

// This is a single-line comment

/*
This is a
multi-line
comment
*/

Console

A debugging tool that allows developers to output messages and data to the browser's console for troubleshooting and testing purposes.

// Output a message
console.log('This is a log message.')

// Output a warning
console.warn('This is a warning message.')

// Output an error
console.error('This is an error message.')

// Output a table
console.table(['JavaScript', 'Python', 'Ruby', 'Java'])

Numbers

Numbers are a primitive data type used to represent numeric values. They can be written with or without a decimal point, and can be either positive or negative.

// Integer number
const integerNumber = 42

// Floating point number
const floatingNumber = 3.14

// Negative number
const negativeNumber = -10

Arithmetic Operators

Arithmetic operators are used in JavaScript to perform arithmetic operations on numeric values.

const a = 5
const b = 10

// Addition
const sum = a + b // => 15

// Subtraction
const difference = b - a // => 5

// Multiplication
const product = a * b // => 50

// Division
const quotient = b / a // => 2

// Modulus
const remainder = b % a // => 0

Strings

Strings are a primitive data type used to represent a sequence of characters. They are enclosed in either single quotes (' '), backticks (` `) or double quotes (" ").

// Single quotes
const name = 'John'

// Double quotes
const message = 'Hello, World!'

// A multi-line string using backticks (`)
const multiLineString = `This is a 
multi-line 
string.
`

String Interpolation & Concatenation

String interpolation and concatenation are both techniques to combine strings and variables.

The key difference between the two is that string interpolation uses placeholders within a string to embed variables, while string concatenation uses the + operator to combine strings and variables.

Here's an example of string concatenation:

const name = 'John'
const age = 30
const message = 'My name is ' + name + ' and I am ' + age + ' years old.'
console.log(message) // => "My name is John and I am 30 years old."

In the above example, the + operator is used to combine the string literals and variables into a single string.

This can become unwieldy with longer or more complex strings, which is where string interpolation comes in handy.

Here's the same example using string interpolation:

const name = 'John'
const age = 30
const message = `My name is ${name} and I am ${age} years old.`
console.log(message) // => "My name is John and I am 30 years old."

In this case, the placeholders ${} are used to embed the variables within the string, making it easier to read and modify.

String interpolation is generally considered to be a more modern and efficient way of combining strings and variables in JavaScript.

Variables

Variables are used to store and manipulate data in a program. They are declared using keywords such as let and const, and can hold values of various data types, including numbers, strings, booleans, and objects.

// Declare a variable called "age" and assign it the value 30
let age = 30

// Declare a constant variable called "name" and assign it the value "John"
const name = 'John'

// Declare a constant variable called "isStudent" and assign it the value true
const isStudent = true

console.log(age) // => 30
console.log(name) // => "John"
console.log(isStudent) // => true

age = 40 // Re-assign the value of the "age" variable
console.log(age) // => 40

let Keyword

The let keyword is used to declare a block-scoped variable, which means that it is only accessible within the block in which it is declared.

What makes let different from const is that the value can be reassigned.

let ringCount
console.log(ringCount) // => undefined

// Attempt to reassign the constant variable
let ringCount = 1
console.log(ringCount) // => 1

if (ringCount === 1) {
  let elfCount = 3 // Declare another variable using let inside a block

  console.log(ringCount) // => 1
  console.log(elfCount) // => 3
}

let ringCount = 2

console.log(ringCount) // => 2
console.log(elfCount) // => Uncaught ReferenceError: elfCount is not defined

const Keyword

The const keyword declares a variable whose value cannot be reassigned. Like let, it is block scoped.

const ringbearer = 'Frodo'
console.log(ringbearer) // => "Frodo"

// Attempt to reassign the constant variable
ringbearer = 'Sam' // => Error: Assignment to constant variable.

if (ringbearer === 'Frodo') {
  const fellowshipMember = 'Legolas' // Declare a constant variable using const inside a block

  console.log(ringbearer) // => "Frodo"
  console.log(fellowshipMember) // => "Legolas"
}

const ringbearer = 'Gollum' // Error: Identifier 'ringbearer' has already been declared

console.log(ringbearer) // => "Gollum"
console.log(fellowshipMember) // => Uncaught ReferenceError: fellowshipMember is not defined

Assignment Operators

Assignment operators are used to assign values to variables.

// "=" assigns a value to a variable
let x = 5;

// "+=" adds a value
let x = 5;
x += 2; // equivalent to x = x + 2
console.log(x); // => 7

// "-=" subtracts a value
let x = 5;
x -= 2; // equivalent to x = x - 2
console.log(x); // => 3

// "_=" multiplies a variable by a value
let x = 5;
x _= 2; // equivalent to x = x \* 2
console.log(x); // 10

// "/=" divides a variable by a value
let x = 5;
x /= 2; // equivalent to x = x / 2
console.log(x); // 2.5

Conditionals

if Statement

The if statement is a control structure that allows developers to execute a block of code only if a specified condition is true.

const age = 18

if (age >= 18) {
  console.log('You are an adult.')
}

// => 'You are an adult.'

if else / else if

The if else and else if statements are both control structures in JavaScript that allow developers to execute different blocks of code depending on different conditions.

The if else statement is used when there are only two possible outcomes based on a condition. It has the following syntax:

if (condition) {
  // Code to be executed if the condition is true
} else {
  // Code to be executed if the condition is false
}

The else if statement is used when there are more than two possible outcomes based on different conditions. It has the following syntax:

if (condition1) {
  // Code to be executed if condition1 is true
} else if (condition2) {
  // Code to be executed if condition2 is true
} else {
  // Code to be executed if all conditions are false
}

An example:

const grade = 85

if (grade >= 90) {
  console.log('A')
} else if (grade >= 80) {
  console.log('B')
} else if (grade >= 70) {
  console.log('C')
} else if (grade >= 60) {
  console.log('D')
} else {
  console.log('F')
}

// => 'B'

Ternary Operator

The ternary operator is a concise way to write an if else statement. It has the following syntax:

condition ? expressionIfTrue : expressionIfFalse

If condition is true, then expressionIfTrue is evaluated and returned. If condition is false, then expressionIfFalse is evaluated and returned. For example:

const age = 18

const message = age >= 18 ? 'You are an adult.' : 'You are not an adult.'

console.log(message) // => 'You are an adult.'

switch Statement

The switch statement is also a control structure to execute different blocks of code depending on the value of a variable. It is often used as an alternative to long chains of if else if statements.

switch (expression) {
  case value1:
    // Code to be executed if expression === value1
    break
  case value2:
    // Code to be executed if expression === value2
    break
  // and so on...
  default:
  // Code to be executed if expression is different from all cases
}

expression is evaluated once and compared with each case value. If a case value is equal to expression, then corresponding block of code is executed.

If none of the case values match, the default block of code is executed (if present). For example:

const color = 'red'

switch (color) {
  case 'red':
    console.log('The color is red.')
    break
  case 'blue':
    console.log('The color is blue.')
    break
  case 'green':
    console.log('The color is green.')
    break
  default:
    console.log('The color is unknown.')
}

// => 'The color is red.'

Operators

Operators are symbols or keywords used in JavaScript to perform various operations on values, such as arithmetic, comparison, logical, and assignment operations.

Comparison Operators

Comparison operators are used to compare two values and return a Boolean value (true or false). They include:

  • > greater than
  • < less than
  • >= greater than or equal to
  • <= less than or equal to
  • === equal to (strict equality)
  • == equal to (no strict equality)
  • !== not equal to (strict inequality)
  • != not equal to (no strict inequality)
const x = 5
const y = 10

console.log(x > y) // => false
console.log(x < y) // => true
console.log(x >= y) // => false
console.log(x <= y) // => true
console.log(x === y) // => false
console.log(x !== y) // => true

Logical Operators

Logical operators are used to combine or negate Boolean values. They include:

  • && logical AND (returns true if both operands are true)
  • || logical OR (returns true if at least one operand is true)
  • ! logical NOT (negates the Boolean value of an operand)
const a = true
const b = false
const c = true

console.log(a && b) // => false
console.log(a || b) // => true
console.log(!a) // => false
console.log(!(a && b)) // => true
console.log((a || b) && c) // => true

Nullish Coalescing Operator

The nullish coalescing operator (??) is a newer operator introduced in JavaScript to provide a more concise way of checking for null or undefined values.

It returns the first operand if it is not null or undefined, and otherwise returns the second operand.

const name = null
const defaultName = 'John'

console.log(name ?? defaultName) // => 'John'

Other Operators

There are also other operators in JavaScript, such as:

  • Arithmetic operators (+, -, *, /, %)
  • Assignment operators (=, +=, -=, *=, /=, %=)
  • Conditional (ternary) operator (condition ? expr1 : expr2)

Difference Between == and === Operators

These comparison operators are used to compare two values for equality.

The == operator performs type coercion, which means it will try to convert the operands to the same type before comparing them.

For example, if you compare a number and a string with ==, JavaScript will try to convert the string to a number before comparing them.

On the other hand, the === operator performs a strict comparison, which means it will only return true if the operands are of the same type and have the same value.

Here are some examples to illustrate the difference:

console.log(0 == false) // => true, 0 is falsy and false is also falsy
console.log(0 === false) // => false, 0 is a number and false is a boolean
console.log(1 == '1') // => true, the string "1" is converted to the number 1
console.log(1 === '1') // => false, number 1 and string "1" are of different types
console.log(null == undefined) // => true, both null and undefined are considered equal when compared with ==
console.log(null === undefined) // => false, null and undefined are of different types and have different values
console.log('0' == false) // => true, the string "0" is converted to the number 0, which is falsy
console.log('0' === false) // => false, the string "0" is not the same type as boolean false

In general, it's recommended to use the === operator for equality comparisons in JavaScript, as it provides more predictable and reliable results.

The == operator can be useful in some cases where you want to allow for type coercion, but it requires careful handling to avoid unexpected behavior.

Functions

Functions

Functions are reusable blocks of code that can be called and executed multiple times with different inputs. A function can accept zero or more parameters, and can return a value to the caller.

function addNumbers(a, b) {
  return a + b
}

const result = addNumbers(3, 5)
console.log(result) // => 8

return Keyword

The return keyword is used to specify the value that a function should return. When a function is called, the code inside the function is executed and any value returned by the return statement is passed back to the caller.

function addNumbers(a, b) {
  return a + b // the sum of `a` and `b` is returned
}

const result = addNumbers(3, 5) // `result` is assigned the value `8` returned by `addNumbers`
console.log(result) // => 8

Function Declaration

Function declaration is one of the ways to define a function in JavaScript. It is a statement that defines a named function and its implementation. Here's an example:

function greet(name) {
  console.log(`Hello, ${name}!`)
}

greet('Alice') // => "Hello, Alice!"

Function declarations are hoisted in JavaScript, which means that they are available for use anywhere in the code, even before they are declared. For example, the following code would still work:

greet('Bob') // => "Hello, Bob!"

function greet(name) {
  console.log(`Hello, ${name}!`)
}

However, it is considered good practice to declare functions before using them, to make the code easier to understand and maintain.

Function Expression

Function expressions are a way of defining functions in JavaScript by assigning a function to a variable. They can be named or anonymous and can be used just like any other value in JavaScript.

const multiplyNumbers = function multiply(a, b) {
return a \* b;
};

const result = multiplyNumbers(3, 5);
console.log(result); // => 15

Anonymous Function

An anonymous function is a function that doesn't have a name. It can be defined using a function expression, which is simply a function defined as a value of a variable.

const greeting = function (name) {
  console.log(`Hello, ${name}!`)
}

greeting('John') // => "Hello, John!"

Function Parameters

Function parameters are the values passed into a function when it is called. Parameters are defined in the function declaration and can be used within the function's code block. Parameters allow the function to accept different input values, making it more flexible and reusable.

function greet(name) {
  console.log(`Hello, ${name}!`)
}

greet('Alice') // => "Hello, Alice!"
greet('Bob') // => "Hello, Bob!"

Arrow Functions (ES6)

Arrow functions are a shorthand syntax for writing functions in JavaScript, introduced in ES6. They are often used in modern JavaScript code due to their concise syntax and the fact that they automatically bind the this keyword to the function's surrounding context.

const calculateArea = (width, height) => {
return width \* height;
}

const area = calculateArea(5, 10);
console.log(area); // => 50

The arrow function syntax consists of the parameter list (in parentheses), an arrow (represented by the => characters), and the function body (in curly braces { }). In the example above, the function takes two parameters, width and height, and returns their product.

If the function body consists of only a single expression, it can be written on a single line without the curly braces:

const calculateArea = (width, height) => width \* height;

Scope

Block vs Function vs Global Scope

In JavaScript, there are three types of scope: block scope, function scope, and global scope.

Block Scope

Block scope refers to the accessibility of variables within a block of code, which is defined by a pair of curly braces {}. Variables declared inside a block are only accessible within that block.

if (true) {
  // Block scope variable
  const message = 'Hello'
  console.log(message) // 'Hello'
}

console.log(message) // ReferenceError: message is not defined

In the example above, message is only accessible inside the if block, and trying to access it outside of the block results in a ReferenceError.

Function Scope

Function scope refers to the accessibility of variables within a function. Variables declared inside a function are only accessible within that function.

function exampleFunction() {
  // Function scope variable
  const message = 'Hello'
  console.log(message) // => 'Hello'
}

exampleFunction()

console.log(message) // => ReferenceError: message is not defined

In the example above, message is only accessible inside the exampleFunction() function, and trying to access it outside of the function results in a ReferenceError.

Global Scope

Global scope refers to the accessibility of variables declared outside of any function or block. Global variables can be accessed from anywhere in the program.

// Global scope variable
const message = 'Hello'

function exampleFunction() {
  console.log(message) // => 'Hello'
}

exampleFunction()

console.log(message) // => 'Hello'

In the example above, message is a global variable that can be accessed from both the exampleFunction() function and outside of any function or block.

let vs var

In JavaScript, let and var are used to declare variables, but they have different scoping rules.

let is a block-scoped variable declaration that was introduced in ES6. Variables declared with let are only accessible within the block they are declared in and any nested blocks.

if (true) {
  let message = 'Hello'
  console.log(message) // 'Hello'
}

console.log(message) // ReferenceError: message is not defined

In the example above, message is only accessible within the if block, and trying to access it outside of the block results in a ReferenceError.

var, on the other hand, is function-scoped. Variables declared with var are accessible throughout the entire function they are declared in, regardless of the block they are declared in. If a variable is declared with var outside of any function, it becomes a global variable and can be accessed throughout the entire program.

if (true) {
  var message = 'Hello'
  console.log(message) // 'Hello'
}

console.log(message) // 'Hello'

In the example above, message is declared with var inside the if block, but is still accessible outside of the block because var is function-scoped. If we had used let instead of var, message would not be accessible outside of the block.

In general, it is recommended to use let and const instead of var to avoid unintended side effects and bugs caused by variable hoisting and scoping issues.

Loops with Closures

When using loops, it's important to understand how scope works in order to avoid unintended consequences. For example, when using var to declare a variable inside a loop, the variable is actually hoisted to the top of the function, and any changes made to it inside the loop will affect the variable's value throughout the entire function. This can cause unexpected behavior and bugs.

Using let or const to declare variables inside loops, on the other hand, creates a new variable with each iteration of the loop, ensuring that each variable has its own distinct value and scope. This is known as loop with closure.

Here's an example that demonstrates the difference between using var and let inside a loop:

// Using var
for (var i = 0; i < 5; i++) {
  setTimeout(function () {
    console.log(i) // prints 5 five times
  }, 1000)
}

// Using let
for (let j = 0; j < 5; j++) {
  setTimeout(function () {
    console.log(j) // prints 0, 1, 2, 3, 4
  }, 1000)
}

In the first loop, i is declared with var, which creates a single variable with global scope. When the loop runs, the setTimeout function is called five times, each time logging the current value of i. However, because i has global scope, its value is set to 5 by the time the setTimeout function is called, so they all log 5.

In the second loop, j is declared with let, which creates a new variable with local scope for each iteration of the loop. When the setTimeout functions are called, they each log the value of their respective j variables, which range from 0 to 4.

Arrays

Definition

Arrays are a data structure that can store a collection of values of any data type, including other arrays. They are declared using square brackets [] and each element is separated by a comma. Elements in an array are accessed using their index, which starts at 0 for the first element.

// An array of numbers
const numbers = [1, 2, 3, 4, 5]

// An array of strings
const fruits = ['apple', 'banana', 'cherry']

// An array of mixed data types
const mixed = ['hello', 42, true]

// Accessing an element in an array
console.log(numbers[0]) // => 1
console.log(fruits[1]) // => 'banana'
console.log(mixed[2]) // => true

Arrays Index

In the context of arrays, an index refers to the position of an element within the array. The first element in the array has an index of 0, the second element has an index of 1, and so on.

Indexes are used to access or modify the elements in an array. This is done by referencing the array name followed by the index of the desired element enclosed in square brackets.

const numbers = [10, 20, 30, 40, 50]

console.log(numbers[0]) // => 10
console.log(numbers[2]) // => 30

// Modifying an element using index
numbers[3] = 45
console.log(numbers) // => [10, 20, 30, 45, 50]

Attempting to access an index that is outside the range of the array will result in an error.

Property.length in Arrays

In JavaScript, length is a property that can be used on various types of data structures, including arrays, strings, and other objects.

When used on an array, the length property returns the number of elements in the array. This value is always one greater than the index of the last element in the array, since array indices start at 0.

const numbers = [10, 20, 30, 40, 50]

console.log(numbers.length) // => 5

The length property can also be used to modify the size of an array by setting it to a new value. If the new value is less than the current length of the array, the elements at the end of the array will be removed. If the new value is greater than the current length of the array, empty slots will be added to the end of the array.

const numbers = [10, 20, 30, 40, 50]

numbers.length = 3
console.log(numbers) // => [10, 20, 30]

numbers.length = 6
console.log(numbers) // => [10, 20, 30, undefined, undefined, undefined]

break and continue in Loops

break and continue are two keywords that can be used in loops to control the flow of the loop.

break Statement

The break statement is used to exit out of a loop before it has finished iterating over all of the elements. This can be useful if you need to stop the loop early if a certain condition is met.

const array = ['apple', 'banana', 'orange', 'pear']

for (let i = 0; i < array.length; i++) {
  if (array[i] === 'orange') {
    break
  }
  console.log(array[i])
}

// => "apple", "banana"

In the example above, the loop will stop when the value of the array is equal to "orange", so the output will be "apple" and "banana".

continue Statement

The continue statement is used to skip over a certain element in the loop and continue on to the next element.

const array = ['apple', 'banana', 'orange', 'pear']

for (let i = 0; i < array.length; i++) {
  if (array[i] === 'orange') {
    continue
  }
  console.log(array[i])
}

// => "apple", "banana", "pear"

In the example above, the loop will skip over the element with a value of "orange", so the output will be "apple", "banana", and "pear".

Nesting

Nesting means that one loop is placed inside another loop. This is a common technique used in programming when you need to iterate over two or more arrays or when you need to perform a certain action on each combination of two or more elements.

Nested For Loops

One way to nest loops is to use nested for loops. This involves placing one for loop inside another for loop. The inner loop will run to completion for each iteration of the outer loop.

const array1 = [1, 2, 3]
const array2 = ['a', 'b', 'c']

for (let i = 0; i < array1.length; i++) {
  for (let j = 0; j < array2.length; j++) {
    console.log(array1[i] + array2[j])
  }
}

// =>
// "1a", "1b", "1c", "2a", "2b", "2c", "3a", "3b", "3c"

In the example above, we have two arrays, and we want to output a combination of each element in the two arrays. The nested for loops allow us to iterate over each element in both arrays and combine them in a specific way.

Nested while Loops

You can also nest while loops to achieve similar results.

const array1 = [1, 2, 3]
const array2 = ['a', 'b', 'c']

let i = 0
while (i < array1.length) {
  let j = 0
  while (j < array2.length) {
    console.log(array1[i] + array2[j])
    j++
  }
  i++
}

// =>
// "1a", "1b", "1c", "2a", "2b", "2c", "3a", "3b", "3c"

The nested while loops work in the same way as the nested for loops, but the syntax is slightly different.

Array Methods

Arrays in JavaScript come with a number of built-in methods that can be used to perform operations on the array. Some of the most commonly used array methods include:

push()

The push() method is used to add one or more elements to the end of an array. It modifies the original array and returns the new length of the array.

const numbers = [1, 2, 3]

numbers.push(4, 5)

console.log(numbers) // => [1, 2, 3, 4, 5]

pop()

The pop() method is used to remove the last element from an array. It modifies the original array and returns the removed element.

const numbers = [1, 2, 3]

const lastElement = numbers.pop()

console.log(numbers) // => [1, 2]
console.log(lastElement) // => 3

shift()

The shift() method is used to remove the first element from an array. It modifies the original array and returns the removed element.

const numbers = [1, 2, 3]

const firstElement = numbers.shift()

console.log(numbers) // => [2, 3]
console.log(firstElement) // => 1

unshift()

The unshift() method is used to add one or more elements to the beginning of an array. It modifies the original array and returns the new length of the array.

const numbers = [1, 2, 3]

numbers.unshift(-2, -1, 0)

console.log(numbers) // => [-2, -1, 0, 1, 2, 3]

splice()

The splice() method is used to add or remove elements from an array at a specified index. It modifies the original array and returns an array containing the removed elements.

const numbers = [1, 2, 3, 4, 5]

// Remove two elements starting at index 2 and insert -1 and 0
const removedElements = numbers.splice(2, 2, -1, 0)

console.log(numbers) // => [1, 2, -1, 0, 5]
console.log(removedElements) // => [3, 4]

slice()

The slice() method is used to create a new array that contains a portion of the elements from the original array. It does not modify the original array.

const numbers = [1, 2, 3, 4, 5]

// Get a new array with elements from index 1 up to but not including index 4
const slicedArray = numbers.slice(1, 4)

console.log(slicedArray) // => [2, 3, 4]

Loops

while Loop

A while loop is a control flow statement in JavaScript that allows code to be executed repeatedly based on a given condition. The loop will continue to run as long as the condition is true, and will stop when the condition becomes false.

let i = 0

while (i < 5) {
  console.log(i)
  i++
}
// => 0, 1, 2, 3, 4

In the example above, the while loop runs as long as the condition i < 5 is true. The loop body prints the current value of i and increments it by 1 in each iteration. Once i becomes equal to 5, the loop exits and the program continues to execute the code after the loop.

for Loop

A for loop is a control flow statement in JavaScript that allows code to be executed repeatedly for a specified number of times. It is often used when the number of iterations is known in advance.

for (let i = 0; i < 5; i++) {
  console.log(i)
}
// => 0, 1, 2, 3, 4

In the example above, the for loop initializes the variable i to 0, checks the condition i < 5, and runs the loop body as long as the condition is true. The loop body prints the current value of i and increments it by 1 in each iteration. Once i becomes equal to 5, the loop exits and the program continues to execute the code after the loop.

The three expressions within the parentheses of a for loop are:

  1. Initialization - this is where you initialize the loop variable to an initial value (e.g. let i = 0).
  2. Condition - this is where you specify the condition that must be true for the loop to continue iterating (e.g. i < 5).
  3. Increment - this is where you specify how the loop variable should be incremented after each iteration (e.g. i++).

for ...of loop

The for...of loop is a type of loop introduced in ES6 that allows you to iterate over iterable objects such as arrays, strings, maps, and sets. It simplifies the process of iterating over an array or other iterable objects by removing the need for a counter variable and by providing direct access to the values.

const arr = [1, 2, 3, 4, 5]

for (const element of arr) {
  console.log(element)
}
// => 1, 2, 3, 4, 5

In the example above, the for...of loop iterates over each element in the array arr and assigns the value of the current element to the variable element. The loop body prints the current value of element.

The for...of loop can also be used with other iterable objects like strings, maps, and sets. Here is an example of iterating over a string using the for...of loop:

const str = 'Hello, world!'

for (const char of str) {
  console.log(char)
}
// => "H", "e", "l", "l", "o", ",", " ", "w", "o", "r", "l", "d", "!"

In the example above, the for...of loop iterates over each character in the string str and assigns the value of the current character to the variable char. The loop body prints the current value of char.

for...in loop

The for...in loop is a type of loop used in JavaScript to iterate over the properties of an object. It is used to loop through the enumerable properties of an object, such as object keys or array indices.

Here's an example of using for...in to loop through the keys of an object:

const obj = { a: 1, b: 2, c: 3 }

for (let key in obj) {
  console.log(key) // => 'a', 'b', 'c'
}

Note that for...in should not be used to loop through an array in JavaScript, as it can produce unexpected results when iterating over non-index properties. Instead, you should use the for...of loop or a regular for loop to iterate over arrays.

Reverse Loop

A reverse loop is a type of loop that iterates over an array or string in reverse order, starting from the last element and ending with the first element.

One way to implement a reverse loop in JavaScript is to use a regular for loop and start the iteration from the last index of the array or string, while decrementing the index at each iteration until it reaches 0.

Here's an example of a reverse loop that iterates over an array in reverse order:

const arr = [1, 2, 3, 4, 5]

for (let i = arr.length - 1; i >= 0; i--) {
  console.log(arr[i]) // => 5, 4, 3, 2, 1
}

Do…While Statement

The do…while statement is a loop statement that executes a block of code at least once, and then continues to execute the block of code as long as the specified condition is true.

let i = 0
do {
  console.log(i)
  i++
} while (i < 5)

// => 0 1 2 3 4

In the example above, the code will always execute at least once, because the condition is evaluated after the first iteration of the loop. If the condition is true, the loop will continue to execute, otherwise it will exit.

Looping Through Arrays

Looping through arrays is a common task in programming. There are several ways to loop through an array in JavaScript, including for loops, forEach method, and for...of loops.

For Loop

A for loop is a traditional loop that is used to iterate over an array.

The loop starts with an initialization of a counter variable, followed by a conditional expression that determines when the loop should stop, and finally an increment statement that increments the counter variable.

const array = ['apple', 'banana', 'orange']

for (let i = 0; i < array.length; i++) {
  console.log(array[i])
}

// => "apple", "banana", "orange"

forEach Method

The forEach method is a higher-order function that can be called on an array. It takes a callback function as its argument, which is called for each element in the array.

const array = ['apple', 'banana', 'orange']

array.forEach(function (element) {
  console.log(element)
})

// => "apple", "banana", "orange"

For...of Loop

The for...of loop is a newer loop statement introduced in ECMAScript 6 (ES6) that simplifies the process of iterating over arrays.

It allows you to iterate over iterable objects, such as arrays, without the need for an index variable.

const array = ['apple', 'banana', 'orange']

for (const element of array) {
  console.log(element)
}

// => "apple", "banana", "orange"

Iterators

Iterators are higher-order functions in JavaScript that allow us to iterate over arrays and perform operations on each element.

Array.forEach()

forEach is used to loop over an array and execute a callback function for each element in the array.

const arr = [1, 2, 3]

arr.forEach((element) => {
  console.log(element)
})

// => 1
// => 2
// => 3

Array.map()

map is used to create a new array by performing a given operation on each element of the original array.

const arr = [1, 2, 3];

const newArr = arr.map((element) => {
return element \* 2;
});
console.log(newArr); // => [2, 4, 6]

Array.filter()

filter is used to create a new array with only the elements that pass a certain condition specified in a callback function.

const arr = [1, 2, 3]

const filteredArr = arr.filter((element) => {
  return element > 1
})
console.log(filteredArr) // => [2, 3]

Array.reduce()

reduce method is used to perform a cumulative operation on an array and return a single value.

const arr = [1, 2, 3]

const sum = arr.reduce((accumulator, currentValue) => {
  return accumulator + currentValue
}, 0)
console.log(sum) // => 6

Objects

Objects are a fundamental data structure in JavaScript. They are used to store collections of related data and functionality. Objects consist of key-value pairs, where the key is a string and the value can be any data type, including other objects.

const person = {
  name: 'Alice',
  age: 30,
  city: 'New York',
  hobbies: ['reading', 'traveling', 'painting'],
  greet: function () {
    console.log(`Hello, my name is ${this.name}. Nice to meet you!`)
  },
}

// Accessing object properties
console.log(person.name) // => "Alice"
console.log(person.age) // => 30

// Adding new properties
person.job = 'Software Engineer'

// Checking for property existence
console.log('name' in person) // => true
console.log('salary' in person) // => false

// Accessing non-existent properties returns undefined
console.log(person.address) // => undefined

Accessing Properties

There are two ways to access properties of an object: dot notation and bracket notation.

Dot notation

Dot notation is the most common way to access properties of an object. It uses a dot followed by the name of the property to access the value of that property.

const person = {
  name: 'John',
  age: 30,
  occupation: 'Developer',
}

console.log(person.name) // => "John"
console.log(person.age) // => 30

Bracket notation

Bracket notation uses square brackets to access the value of a property. The name of the property is passed as a string inside the square brackets.

const person = {
  name: 'John',
  age: 30,
  occupation: 'Developer',
}

console.log(person['name']) // => "John"
console.log(person['age']) // => 30

Bracket notation is especially useful when the name of the property is stored in a variable.

const person = {
  name: 'John',
  age: 30,
  occupation: 'Developer',
}

const propertyName = 'name'
console.log(person[propertyName]) // => "John"

Object Mutation

Objects are mutable, which means that you can modify their properties even after they have been created.

const person = {
  name: 'Alice',
  age: 30,
  city: 'New York',
  hobbies: ['reading', 'traveling', 'painting'],
}

// Modifying object properties
person.age = 31
person.hobbies.push('gardening')

// Adding new properties
person.job = 'Software Engineer'

console.log(person) // => {name: "Alice", age: 31, city: "New York", hobbies: ["reading", "traveling", "painting", "gardening"], job: "Software Engineer"}

Factory Functions

A factory function is a function that returns an object. It is called a factory function because it creates and returns a new object each time it is called.

Factory functions are often used to create objects that have similar properties or methods. The advantage of using a factory function is that it allows you to create multiple objects with the same properties and methods without having to repeat the code for creating those objects.

Here is an example of a factory function that creates person objects:

function createPerson(name, age, occupation) {
  return {
    name: name,
    age: age,
    occupation: occupation,
    greet: function () {
      console.log(`Hello, my name is ${this.name}.`)
    },
  }
}

const john = createPerson('John', 30, 'Developer')
const jane = createPerson('Jane', 25, 'Designer')

john.greet() // => "Hello, my name is John."
jane.greet() // => "Hello, my name is Jane."

delete Operator

The delete operator can be used to remove a property from an object.

const person = {
  name: 'John',
  age: 30,
  city: 'New York',
}

delete person.city

console.log(person) // => { name: 'John', age: 30 }

Objects as Arguments

Objects can be passed as arguments to functions, allowing for more complex data to be processed within the function.

function printPerson(person) {
  console.log(`Name: ${person.name}, Age: ${person.age}, City: ${person.city}`)
}

const john = {
  name: 'John',
  age: 30,
  city: 'New York',
}

printPerson(john) // => Name: John, Age: 30, City: New York

this Keyword

The this keyword refers to the object that the method or function is being called on. It allows a method or function to access and manipulate the properties of the object it belongs to.

const person = {
  name: 'John',
  age: 30,
  sayHello: function () {
    console.log(
      `Hello, my name is ${this.name} and I am ${this.age} years old.`,
    )
  },
}

person.sayHello() // => Hello, my name is John and I am 30 years old.

Getters and Setters

Getters and setters are methods that can be defined on an object to control access to its properties.

A getter is a method that is used to get the value of a property. It is defined using the get keyword and does not take any arguments. When the property is accessed, the getter is called and its return value is used as the value of the property.

const obj = {
  get name() {
    return 'John'
  },
}

console.log(obj.name) // => "John"

A setter is a method that is used to set the value of a property. It is defined using the set keyword and takes a single argument which is the new value of the property. When the property is set, the setter is called with the new value as its argument.

const obj = {
\_name: "",
set name(name) {
this.\_name = name;
}
};

obj.name = "John";
console.log(obj.\_name); // => "John"

Getters and setters are often used to control access to private properties, which are properties that should not be accessed or modified directly from outside the object. By using getters and setters, we can provide a controlled interface for accessing and modifying these properties.

Classes

Class

A class is a blueprint for creating objects with similar properties and methods. It provides a way to create objects with predefined properties and methods that can be shared among multiple instances of that class.

class Person {
  constructor(name, age) {
    this.name = name
    this.age = age
  }

  sayHello() {
    console.log(
      `Hello, my name is ${this.name} and I am ${this.age} years old.`,
    )
  }
}

const person1 = new Person('John', 30)
person1.sayHello() // => "Hello, my name is John and I am 30 years old."

Class Constructor

A class constructor is a special method that is called when an instance of the class is created using the new keyword. It is used to set initial values for the properties of the object being created.

class Person {
  constructor(name, age) {
    this.name = name
    this.age = age
  }
}

const person1 = new Person('John', 30)
console.log(person1.name) // => "John"
console.log(person1.age) // => 30

Class Methods

Class methods are functions that are defined on a class and can be called on instances of that class. They are used to perform actions or calculations using the properties of the object.

class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}

// Method to calculate the area of the rectangle
calculateArea() {
return this.height \* this.width;
}
}

const rectangle1 = new Rectangle(10, 5);
console.log(rectangle1.calculateArea()); // => 50

Static Method

Classes can have static methods, which are methods that are called on the class itself rather than on an instance of the class. They are defined using the static keyword.

class Calculator {
  static add(a, b) {
    return a + b
  }
}

console.log(Calculator.add(2, 3)) // => 5

extends

extends is used to create a subclass, which inherits properties and methods from a superclass. The subclass can also have its own properties and methods, and can override or extend the properties and methods of the superclass.

class Animal {
  constructor(name) {
    this.name = name
  }

  speak() {
    console.log(this.name + ' makes a noise.')
  }
}

class Dog extends Animal {
  speak() {
    console.log(this.name + ' barks.')
  }
}

const dog1 = new Dog('Rufus')
dog1.speak() // => "Rufus barks."

Modules

Modules are used to organize code into separate files or modules, making it easier to manage and maintain larger applications. There are two main ways to work with modules.

ES6 export and import

ES6 export and import is a feature introduced in ECMAScript 6 (ES6) that allows you to export and import functions, objects, or values from one module to another.

// person.js module
export const name = 'John'
export function sayHello() {
  console.log('Hello!')
}

// main.js module
import { name, sayHello } from './person.js'
console.log(name) // => "John"
sayHello() // => "Hello!"

CommonJS module.exports and require()

module.exports and require() is a feature that was introduced in CommonJS and is still commonly used in Node.js. It allows you to export and import functions, objects, or values from one module to another. Here's an example:

// person.js module
const name = 'John'
function sayHello() {
  console.log('Hello!')
}
module.exports = { name, sayHello }

// main.js module
const { name, sayHello } = require('./person.js')
console.log(name) // => "John"
sayHello() // => "Hello!"

Note that module.exports and require() are still used in Node.js, while ES6 export and import are more used in modern browsers and can be transpiled using tools like Babel. However, export and import work in newer versions of Node.js.

Promises

Promises are a way to handle asynchronous operations in JavaScript. They represent a value that may not be available yet but will be at some point in the future. A promise can be in one of three states:

  • Pending: The initial state of a promise. The operation represented by the promise is still in progress.
  • Fulfilled: The operation represented by the promise has completed successfully, and the resulting value is available.
  • Rejected: The operation represented by the promise has failed, and the reason for the failure is available.
const myPromise = new Promise((resolve, reject) => {
  // Do some asynchronous operation here
  if (operationSuccessful) {
    resolve(result) // The operation completed successfully, pass the result
  } else {
    reject(error) // The operation failed, pass the error
  }
})

myPromise
  .then((result) => {
    // Handle the result
  })
  .catch((error) => {
    // Handle the error
  })

The then() method is called when the promise is fulfilled, and the catch() method is called when the promise is rejected.

Promise.all()

Promise.all() is a method in JavaScript that takes an iterable of promises and returns a new promise that resolves to an array of the results of all the input promises, in the same order as the input promises.

If any of the input promises reject, then the returned promise will reject with the reason of the first rejected promise. If any of the input promises are not promises, they are converted to promises using Promise.resolve().

const promise1 = Promise.resolve(1)
const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 1000, 'foo')
})
const promise3 = 42

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values) // => [1, 'foo', 42]
})

Async/Await

async/await is a newer syntax for handling asynchronous operations in JavaScript. It is built on top of promises and provides a more concise way to write asynchronous code that is easier to read and understand.

The async keyword is used to define an asynchronous function, which returns a promise. Inside an async function, you can use the await keyword to wait for the resolution of a promise before continuing with the execution of the function.

async function fetchUserData(userId) {
  const response = await fetch(
    `https://jsonplaceholder.typicode.com/users/${userId}`,
  )
  const user = await response.json()
  return user
}

fetchUserData(1).then((user) => {
  console.log(user.name) // => "Leanne Graham"
})

In this example, fetchUserData() is an asynchronous function that uses the await keyword to wait for the resolution of two promises: the first is returned by the fetch() method, which makes a network request to fetch user data, and the second is returned by the json() method, which parses the response as JSON.

When fetchUserData() is called with a userId argument of 1, it returns a promise that resolves to an object representing the user with an ID of 1. The then() method is called on the returned promise and logs the name of the user.

async/await makes it easier to write asynchronous code that looks more like synchronous code. It also simplifies error handling, since you can use try/catch blocks to handle errors that occur during asynchronous operations.

Error Handling

Error handling is an important part of any program, especially when dealing with asynchronous operations. In JavaScript, you can handle errors using try/catch blocks and the catch() method on promises.

With try/catch, you can wrap your asynchronous code in a try block and catch any errors that occur in the catch block:

async function fetchData() {
  try {
    const response = await fetch('https://example.com/data')
    const data = await response.json()
    return data
  } catch (error) {
    console.log('An error occurred:', error)
    throw error
  }
}

fetchData().catch((error) => {
  console.log('Error caught in the outer catch block:', error)
})

In this example, fetchData() is an asynchronous function that fetches data from an API using the fetch() method and parses the response as JSON. If an error occurs during this process, the catch block will log the error and throw it, causing the outer catch block to catch it as well.

You can also use the catch() method on a promise to handle errors:

fetch('https://example.com/data')
  .then((response) => {
    if (!response.ok) {
      throw new Error('Network response was not ok')
    }
    return response.json()
  })
  .then((data) => {
    console.log(data)
  })
  .catch((error) => {
    console.log('An error occurred:', error)
  })

In this example, the fetch() method returns a promise that resolves to a response object. We use the ok property of the response object to check if the network response was successful.

If it wasn't, we throw an error. If it was, we parse the response as JSON and log the data. If an error occurs during any of these steps, the catch block will log the error.

Requests

Requests are a way for a client (e.g., a web browser or a mobile app) to communicate with a server and exchange data. There are various ways to make requests, and here are some common ones:

JSON

JSON (JavaScript Object Notation) is a lightweight data interchange format that is easy for humans to read and write and easy for machines to parse and generate.

It is often used for exchanging data between a client and a server in web applications. Here's an example of creating a JSON object in JavaScript:

const person = {
  name: 'John',
  age: 30,
  email: 'john@example.com',
}

Formatting JSON

In a web application, the server often needs to send JSON data back to the client in response to a request. In Node.js, this can be achieved by using the res.json() method of the response object.

Here's an example of sending a JSON response in Node.js:

app.get('/person', (req, res) => {
  const person = {
    name: 'John',
    age: 30,
    email: 'john@example.com',
  }
  res.json(person)
})

XMLHttpRequest (XHR)

XMLHttpRequest (XHR) is a JavaScript API that allows us to send HTTP requests and receive responses in the background without having to reload the web page. It is commonly used in AJAX (Asynchronous JavaScript and XML) web applications.

Here's an example of making a GET request using XHR:

const xhr = new XMLHttpRequest()
xhr.open('GET', 'https://example.com/data')
xhr.send()
xhr.onreadystatechange = function () {
  if (xhr.readyState === 4 && xhr.status === 200) {
    console.log(xhr.responseText)
  }
}

GET Request

GET is a HTTP method that is used to retrieve information from a server. In a web application, GET requests are commonly used to fetch data from a server and display it on a web page.

fetch('https://example.com/data')
  .then((response) => response.json())
  .then((data) => console.log(data))

POST Request

POST is a HTTP method that is used to submit data to a server. In a web application, POST requests are commonly used to send form data to a server for processing.

const data = { username: 'John', password: 'password' };

fetch('https://example.com/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
})å
.then(response => response.json())
.then(data => console.log(data));

Note that in this example, we are sending a JSON string in the request body, so we need to set the Content-Type header to application/json.

Conclusion

In summary, JavaScript is a versatile programming language that is widely used for web development. It can be overwhelming to remember all the concepts, methods, and functions, even for experienced developers, which is why a cheat sheet can be incredibly helpful.

This cheat sheet covers the most important topics, including basics, conditionals, functions, scope, arrays, loops, iterators, objects, classes, modules, promises, async/await, and requests.

It provides a quick reference guide for both the beginner and the more experienced developer. If there is anything I have missed, please let me know. I hope this has been of some help!