Functions: Definition, Parameters, Return Values
Functions are reusable blocks of code. They’re fundamental to JavaScript programming.
Function Declaration
The most common way to define a function:
function greet(name) {
return `Hello, ${name}!`;
}
console.log(greet("Alice")); // "Hello, Alice!"
Anatomy
function functionName(parameter1, parameter2) {
// Function body
return result;
}
- function: keyword
- functionName: identifier
- parameters: inputs (optional)
- return: output (optional)
Function Expression
Assigning a function to a variable:
const add = function(a, b) {
return a + b;
};
console.log(add(2, 3)); // 5
Anonymous Functions
Functions without names:
const multiply = function(a, b) {
return a * b;
};
Arrow Functions
Modern syntax introduced in ES6:
const subtract = (a, b) => {
return a - b;
};
console.log(subtract(5, 2)); // 3
Concise Syntax
For single expressions, omit braces and return:
const square = x => x * x;
console.log(square(4)); // 16
const greet = name => `Hello, ${name}!`;
console.log(greet("Bob")); // "Hello, Bob!"
Multiple Parameters
const add = (a, b) => a + b;
const multiply = (a, b) => a * b;
// No parameters
const random = () => Math.random();
Parameters and Arguments
Default Parameters
function greet(name = "Guest") {
return `Hello, ${name}!`;
}
console.log(greet()); // "Hello, Guest!"
console.log(greet("Alice")); // "Hello, Alice!"
Rest Parameters
Collect remaining arguments into an array:
function sum(...numbers) {
return numbers.reduce((a, b) => a + b, 0);
}
console.log(sum(1, 2, 3, 4, 5)); // 15
Destructuring Parameters
function displayPerson({ name, age }) {
console.log(`${name} is ${age} years old`);
}
displayPerson({ name: "Alice", age: 30 }); // "Alice is 30 years old"
Return Values
Single Return
function isEven(num) {
return num % 2 === 0;
}
console.log(isEven(4)); // true
console.log(isEven(5)); // false
Multiple Returns
function divideWithRemainder(a, b) {
return [Math.floor(a / b), a % b];
}
const [quotient, remainder] = divideWithRemainder(17, 5);
console.log(quotient, remainder); // 3, 2
Early Return
function processUser(user) {
if (!user) {
return "No user provided";
}
if (!user.name) {
return "User has no name";
}
return `Processing ${user.name}`;
}
No Return
Functions without return statements return undefined:
function logMessage(msg) {
console.log(msg);
// implicitly returns undefined
}
const result = logMessage("Hello"); // undefined
Scope and Closures
Function Scope
Variables inside a function are local:
function example() {
const local = "inside";
console.log(local); // "inside"
}
console.log(local); // ReferenceError
Global Scope
Variables outside functions are global:
const global = "outside";
function example() {
console.log(global); // "outside"
}
Closures
Inner functions can access outer function variables:
function outer() {
const message = "Hello";
function inner() {
console.log(message); // Can access outer's variable
}
return inner;
}
const fn = outer();
fn(); // "Hello"
Practical Examples
Validation Function
function validateEmail(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
}
console.log(validateEmail("[email protected]")); // true
console.log(validateEmail("invalid")); // false
Calculator
function calculate(a, b, operation = "add") {
switch(operation) {
case "add":
return a + b;
case "subtract":
return a - b;
case "multiply":
return a * b;
case "divide":
return b !== 0 ? a / b : "Cannot divide by zero";
default:
return "Unknown operation";
}
}
console.log(calculate(10, 5, "add")); // 15
console.log(calculate(10, 5, "multiply")); // 50
Array Processor
function processArray(arr, callback) {
const result = [];
for (let item of arr) {
result.push(callback(item));
}
return result;
}
const numbers = [1, 2, 3, 4, 5];
const doubled = processArray(numbers, x => x * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
Function Hoisting
Function declarations are hoisted:
console.log(greet("Alice")); // Works! "Hello, Alice!"
function greet(name) {
return `Hello, ${name}!`;
}
But function expressions are not:
console.log(add(2, 3)); // TypeError: add is not a function
const add = function(a, b) {
return a + b;
};
Best Practices
Use Descriptive Names
// Good
function calculateTotalPrice(items) { }
// Bad
function calc(x) { }
Keep Functions Small
// Good - single responsibility
function validateEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
// Bad - doing too much
function validateAndSendEmail(email) {
// validation logic
// sending logic
}
Use Default Parameters
// Good
function greet(name = "Guest") {
return `Hello, ${name}!`;
}
// Avoid
function greet(name) {
name = name || "Guest";
return `Hello, ${name}!`;
}
Prefer Arrow Functions for Callbacks
// Good
const numbers = [1, 2, 3];
const doubled = numbers.map(x => x * 2);
// Less clean
const doubled = numbers.map(function(x) {
return x * 2;
});
Related Resources
Official Documentation
External Resources
Summary
- Function declaration:
function name() {} - Function expression:
const name = function() {} - Arrow function:
const name = () => {} - Parameters: can have defaults, rest parameters, destructuring
- Return: explicit or implicit (undefined)
- Scope: functions create local scope
- Closures: inner functions access outer scope
Next Steps
- Arrow Functions and Function Expressions
- Scope and Hoisting in JavaScript
- Closures: Understanding Function Scope
- The ’this’ Keyword and Context Binding
- Callbacks and Asynchronous JavaScript
Comments