Functions and Closures
Defining functions, closures, and arrow functions
Introduction
In this lesson, you'll learn about functions and closures in JavaScript. Coming from Python, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.
In Python, you're familiar with defining functions, closures, and arrow functions.
JavaScript has its own approach to defining functions, closures, and arrow functions, which we'll explore step by step.
The JavaScript Way
Let's see how JavaScript handles this concept. Here's a typical example:
// Function declaration
function greet(name, greeting = "Hello") {
return `${greeting}, ${name}!`;
}
// Arrow function (lambda equivalent)
const square = x => x ** 2;
// Rest params and spread
function log(...args) {
console.log(args);
}
// Closure
function makeCounter() {
let count = 0;
return function increment() {
count++;
return count;
};
}
const counter = makeCounter();
counter(); // 1
counter(); // 2Comparing to Python
Here's how you might have written similar code in Python:
# Function definition
def greet(name, greeting="Hello"):
return f"{greeting}, {name}!"
# Lambda
square = lambda x: x ** 2
# *args and **kwargs
def log(*args, **kwargs):
print(args, kwargs)
# Closure
def make_counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
counter = make_counter()
counter() # 1
counter() # 2You may be used to different syntax or behavior.
Arrow functions ≈ lambda (but can span multiple lines)
You may be used to different syntax or behavior.
...rest params ≈ *args / no direct **kwargs equivalent
You may be used to different syntax or behavior.
Closures work identically — no nonlocal needed in JS
You may be used to different syntax or behavior.
Default params look the same in both
Step-by-Step Breakdown
1. Arrow Functions
JavaScript arrow functions are more flexible than Python lambdas — they can contain multiple statements.
square = lambda x: x ** 2const square = x => x ** 2;
// Multi-line:
const abs = x => {
if (x < 0) return -x;
return x;
};2. Rest Parameters
...rest collects extra arguments into an array, similar to Python's *args.
def fn(*args, **kwargs): ...function fn(...args) { /* args is Array */ }3. Closures
JavaScript closures capture variables by reference, just like Python. No nonlocal keyword needed.
nonlocal count
count += 1// Just reference it — JS closures capture by reference
count++;Common Mistakes
When coming from Python, developers often make these mistakes:
- Arrow functions ≈ lambda (but can span multiple lines)
- ...rest params ≈ *args / no direct **kwargs equivalent
- Closures work identically — no nonlocal needed in JS
Key Takeaways
- Arrow functions are multi-line lambdas
- ...rest ≈ *args, no built-in **kwargs
- Closures work identically — no nonlocal