Functions are simply blocks of reusable code designed to perform specific tasks. The function is defined and contains a logic that is to be executed when called or invoked.
Important Note: Without the
returnkeyword, a function will returnundefined. If you need a function to produce an output value, make sure to includereturn. That said, not every function needs one — functions that perform side effects like logging to the console, updating the DOM, or modifying an array in place are often intentionally written without areturn.
Functions allow us to encapsulate logic for reusability, handle input and produce output, manage asynchronous code, and create modular, clean code.
Defining Functions
A function can be defined (or created) in three main ways:
1. Function Declaration
The most traditional way to define a function. It requires the function keyword, the name, parameters (if any), and the logic inside curly braces.
function greet(name) {
return `Hello, ${name}!`;
}
Function declarations are hoisted — meaning they are loaded into memory before the code runs, so they can be called before they appear in the file without throwing an error.
console.log(greet("Alice")); // Works fine — declaration is hoisted
function greet(name) {
return `Hello, ${name}!`;
}
2. Function Expression
Functions assigned to variables. When assigned to a variable, the variable name effectively acts as the function name.
const greet = function(name) {
// This is an anonymous function expression assigned to a variable
return `Hello, ${name}!`;
};
Function expressions are not hoisted in the same way. Because they are assigned to a const or let variable, calling them before their definition throws a ReferenceError.
console.log(greet("Alice")); // ReferenceError: Cannot access 'greet' before initialization
const greet = function(name) {
return `Hello, ${name}!`;
};
3. Arrow Function (ES6)
A concise way to write functions, particularly useful for short, one-liner tasks.
const greet = (name) => `Hello, ${name}!`;
Like function expressions, arrow functions are also not hoisted — they must be defined before they are called.
Calling a Function
To execute a function, you call it by its name and provide the required arguments (if any) inside parentheses:
console.log(greet("Alice")); // Output: Hello, Alice!
Parameters and Arguments
While often used interchangeably, these terms have distinct roles:
- Parameters: Placeholders defined in the function signature.
- Arguments: The actual values passed when calling the function.
function add(a, b) { // a and b are Parameters
return a + b;
}
console.log(add(5, 3)); // 5 and 3 are Arguments
Key Function Concepts
Function Scope
Variables declared inside a function are not accessible outside of it. This ensures data privacy.
function scopedFunction() {
let secret = "I am private!";
console.log(secret); // Accessible here
}
scopedFunction();
console.log(secret); // Error: secret is not defined
Default Parameters
Functions can have default values. If no argument is provided during the call, the default value is used.
function greet(name = "Guest") {
return `Hello, ${name}!`;
}
console.log(greet()); // Output: Hello, Guest!
Anonymous Functions
Functions without a name are called anonymous functions. They are frequently used in expressions or as callbacks.
Direct Calls vs. Event-Driven Execution
While "calling" and "invoking" are used interchangeably in JavaScript, it is worth understanding the difference between two patterns of function execution:
| Aspect | Direct Call | Event-Driven Execution |
|---|---|---|
| Definition | You explicitly execute the function by name at a specific point in the code. | The function is passed as a callback or attached to an event, and the environment decides when to run it. |
| Example | greet("Alice"); | button.addEventListener("click", sayHello); |
| Control | You control exactly when it runs. | Execution depends on an external trigger like a user action or a timer. |