JavaScript
Getting Started
Package Management
pnpm init -y
# Creates a package.json file
# Add a dependency
pnpm add foo
# Add a dev dependency
pnpm add -D bar
# Install all dependencies
pnpm install
Run File
node myfile.js
Run Project
First, add a start script to your package.json file.
"scripts": {
"start": "node index.js"
}
Then, run the project.
pnpm start
Core Concepts
Declarations
let- mutable variableconst- immutable variablevar- old way to declare variables
Scopes
letandconstare block scoped. A block is defined by curly braces{}varis function scoped
Functions
- Functions are first-class citizens
- Can be assigned to variables, passed as arguments, and returned from other functions
- In function declarations and expressions, if
returnis omitted, the function will returnundefined. - In arrow functions,
returncan be implicitly returned if- the body is a single expression
- AND the function is written without curly braces
// Function declaration (explicit return)
function greet(name) {
return `Hello, ${name}!`;
}
// Function expression (explicit return)
const greet = function(name) {
return `Hello, ${name}!`;
};
// Arrow function (implicit return)
const greet = (name) => `Hello, ${name}!`;
// Arrow function (explicit return)
const greet = (name) => { return `Hello, ${name}!` };
You can have parameters with default values with =.
// Default parameter
function greet(name = 'World') {
return `Hello, ${name}!`;
}
// Handling optional parameters manually
function greet(name) {
// Check if name is undefined
return `Hello, ${name || 'World'}!`;
}
Collections
Arrays
Arrays are ordered lists of values
const numbers = [1, 2, 3];
numbers[0] = 0; // Access/set by index
numbers.push(4); // Append to end
numbers.pop(); // Remove from end
numbers.shift(); // Remove from beginning
numbers.unshift(0); // Prepend to beginning
// Destructure array
const [first, second, third] = numbers;
// Swap
[first, second] = [second, first];
// Spread operator
const newNumbers = [1, 2, ...numbers];
There are many ways to loop through arrays.
// Loop
for (const number of numbers) {
console.log(number);
}
// Loop with index
for (let i = 0; i < numbers.length; i++) {
console.log(numbers[i]);
}
// forEach
numbers.forEach(number => {
console.log(number);
});
// forEach with index
numbers.forEach((number, index) => {
console.log(number, index);
});
Operations on arrays
// Map
const doubled = numbers.map(number => number * 2);
// [2, 4, 6]
// Filter
const evenNumbers = numbers.filter(number => number % 2 === 0);
// [2, 4]
// Reduce - accumulates
const sum = numbers.reduce((acc, number) => acc + number, 0);
// 6
Sets
- Sets are ordered collections of unique values
const set = new Set();
set.add('John');
set.add('Jane');
set.add('John'); // Duplicate, ignored
set.has('John'); // true
set.size; // 2
set.delete('Jane');
set.clear();
Iterate over sets
for (const value of set) {
console.log(value);
}
Objects
- Objects are unordered collections of key-value pairs
- Keys are strings or symbols, and values can be any type
- Use dot notation or bracket notation to access properties
const person = {
name: 'John',
age: 30,
};
// Access properties
person.name;
person['name'];
// Delete properties
delete person.age;
Loop through object properties
// Keys
for (const key in person) {
console.log(key, person[key]);
}
// Values
for (const value of Object.values(person)) {
console.log(value);
}
// Keys and values
for (const [key, value] of Object.entries(person)) {
console.log(key, value);
}
Maps
- Maps are ordered collections of key-value pairs
- Keys can be any type
const map = new Map();
map.set('name', 'John');
map.set('age', 30);
map.get('name'); // John
map.has('name'); // true
map.size; // 2
map.delete('age');
map.clear();
Asynchronous Code
Promises
// Creating a promise
const fetchData = new Promise((resolve, reject) => {
// Async operation
const success = true;
if (success) {
resolve('Data fetched successfully');
} else {
reject('Error fetching data');
}
});
// Using promises
fetchData
.then(data => console.log(data))
.catch(error => console.error(error));
Async/Await
// Async function declaration
async function fetchUser(id) {
try {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Error fetching user:', error);
throw error;
}
}
// Using async functions
fetchUser(123)
.then(user => console.log(user))
.catch(error => console.error(error));
Error Handling
Try/Catch
try {
// Code that might throw an error
} catch (error) {
// Code that runs if an error is thrown
} finally {
// Code that runs after the try/catch block
}
Throw
throw is equivalent to raise in Python.
throw new Error('Something went wrong');
Assert
// Node.js
const assert = require('assert');
assert(condition, 'Message');
// Or in testing frameworks like Jest
import { expect } from '@jest/globals';
expect(condition).toBeTruthy();
Type Checking
Checking class instances (supports inheritance)
- JavaScript
- Python
class Animal {}
class Dog extends Animal {}
const d = new Dog();
console.log(d instanceof Dog); // true
console.log(d instanceof Animal); // true
class Animal: pass
class Dog(Animal): pass
d = Dog()
print(isinstance(d, Dog)) # True
print(isinstance(d, Animal)) # True
Checking exact type (ignores inheritance)
- JavaScript
- Python
console.log(Object.getPrototypeOf(d) === Dog.prototype); // true
console.log(Object.getPrototypeOf(d) === Animal.prototype); // false
print(type(d) is Dog) # True
print(type(d) is Animal) # False
Checking primitives
- JavaScript
- Python
let x = 42;
console.log(typeof x === "number"); // true
x = 42
print(isinstance(x, int)) # True
print(type(x) is int) # True
JavaScript vs Python Type Checking
- Python's isinstance is more flexible (works on both classes and built-in types), whereas TypeScript's instanceof only works for class instances.
- TypeScript's typeof is only for primitives, whereas Python's type() works on any object.
- Python supports multiple types in isinstance(obj, (type1, type2)), but TypeScript requires multiple typeof checks.
Testing
Jest
If you’re using Create React App (CRA), Jest and React Testing Library are already included. Otherwise, install the required dependencies:
npm install --save-dev jest @testing-library/react @testing-library/jest-dom @testing-library/user-event
Unit Testing
// src/components/Button.test.jsx
import { render, screen, fireEvent } from "@testing-library/react";
import Button from "./Button";
test("renders button with correct label", () => {
render(<Button label="Click Me" />);
expect(screen.getByText("Click Me")).toBeInTheDocument();
});
test("calls onClick handler when clicked", () => {
const handleClick = jest.fn(); // Mock function
render(<Button label="Click Me" onClick={handleClick} />);
fireEvent.click(screen.getByText("Click Me"));
expect(handleClick).toHaveBeenCalledTimes(1);
});
npm test
Integration Testing
// src/components/Counter.test.jsx
import { render, screen, fireEvent } from "@testing-library/react";
import Counter from "./Counter";
test("increments counter when button is clicked", () => {
render(<Counter />);
const button = screen.getByText("Increment");
fireEvent.click(button);
expect(screen.getByText("Count: 1")).toBeInTheDocument();
});