Functions in JavaScript
Learn how to define and use functions in JavaScript - declarations, arrow functions, parameters, scope, closures, and higher-order functions with Docker-ready examples
Functions are the heart of JavaScript. As a multi-paradigm language with strong functional roots (it was originally meant to embed Scheme), JavaScript treats functions as first-class values - they can be stored in variables, passed as arguments, returned from other functions, and created on the fly. This is what makes patterns like callbacks, promises, and event handlers possible.
JavaScript offers several ways to define a function, and they are not interchangeable. Function declarations are hoisted and bring their own this; arrow functions are compact and inherit this from their surrounding scope. Understanding which to reach for is a core JavaScript skill.
In this tutorial you will learn how to declare functions, pass parameters (including default values and the rest operator), understand variable scope and closures, write recursive functions, and use higher-order functions - functions that operate on other functions.
Defining and Calling Functions
The most traditional way to define a function is the function declaration. JavaScript also supports function expressions (storing a function in a variable) and arrow functions (a concise ES6 syntax).
Create a file named functions_basics.js:
| |
Function declarations are hoisted, meaning they are available throughout their scope even before the line where they are written. Function expressions and arrow functions assigned to const are not - you must define them before use.
Parameters: Defaults and Rest
JavaScript parameters are flexible. Any argument you omit is undefined, you can give parameters default values, and the rest parameter (...args) collects an arbitrary number of arguments into an array.
Create a file named functions_params.js:
| |
Scope and Closures
A closure is a function that “remembers” the variables from the scope in which it was created, even after that scope has finished executing. Closures are one of JavaScript’s most powerful features and the foundation of data privacy and stateful callbacks.
Create a file named functions_scope.js:
| |
The count variable lives on inside the returned function. Each call to makeCounter() produces a fresh, independent closure - which is why other starts back at 1.
Recursion
A function that calls itself is recursive. JavaScript supports recursion naturally; here is the classic factorial.
Create a file named functions_recursion.js:
| |
Every recursive function needs a base case - a condition that stops the recursion - otherwise it would call itself forever and throw a “Maximum call stack size exceeded” error.
Higher-Order Functions
Because functions are first-class values, JavaScript can pass them around like any other data. A higher-order function either takes a function as an argument, returns a function, or both. The array methods map, filter, and reduce are everyday examples.
Create a file named functions_higher_order.js:
| |
Running with Docker
| |
Expected Output
Running functions_basics.js:
Hello, Ada!
square(5) = 25
cube(3) = 27
----------
----------
Return of logSeparator: undefined
Running functions_params.js:
Grace (guest)
Linus (admin)
sum() = 0
sum(1, 2, 3, 4) = 10
http://example.com:80/
http://example.com:8080/api
Running functions_scope.js:
inner sees: local and global
count: 1
count: 2
count: 3
other count: 1
Running functions_recursion.js:
factorial(5) = 120
factorial(0) = 1
fib(10) = 55
Running functions_higher_order.js:
doubled: [ 2, 4, 6, 8, 10, 12 ]
evens: [ 2, 4, 6 ]
total: 21
triple(7) = 21
Key Concepts
- Three ways to define functions - declarations (hoisted), expressions, and arrow functions; they differ in hoisting and how they handle
this. - Functions are first-class values - they can be stored in variables, passed as arguments, and returned from other functions.
- Default and rest parameters -
param = valuesupplies fallbacks, while...argscollects a variable number of arguments into an array. - Closures capture their environment - an inner function retains access to outer variables even after the outer function returns, enabling private state.
- Recursion needs a base case - without a terminating condition, recursive calls overflow the call stack.
- Higher-order functions power functional JavaScript -
map,filter, andreduceplus function factories let you compose behavior from small reusable pieces. - Arrow functions are concise but different - they inherit
thisfrom the surrounding scope, making them ideal for callbacks but unsuitable as object methods that rely onthis.
Comments
Loading comments...
Leave a Comment