Introduction to Functions
Functions are fundamental building blocks in JavaScript. They encapsulate reusable code, enable abstraction, and form the basis of many advanced patterns. A function is a block of code designed to perform a particular task. JavaScript functions are first-class objects, meaning they can be assigned to variables, passed as arguments, returned from other functions, and have properties. Understanding functions deeply is crucial for mastering JavaScript.
Function Declarations
Function declarations define named functions. They are hoisted, meaning they can be called before they appear in the code. Syntax: function functionName(parameters) { /* code */ }. Example: function add(a, b) { return a + b; }. Declarations are great for named functions that need to be accessible throughout their scope. They improve code readability and are ideal for recursion since the function name is available within the function body.
Function Expressions
Function expressions define functions as part of an expression. They can be named or anonymous. Example: const multiply = function(a, b) { return a * b; }. Unlike declarations, expressions are not hoisted. They are assigned to variables and invoked via the variable name. Named function expressions allow recursion and stack traces. Function expressions enable callbacks, closures, and many functional programming patterns.
Arrow Functions
Arrow functions provide a concise syntax. Example: const double = x => x * 2;. They have no own this, arguments, or super bindings. They inherit this from enclosing lexical scope. Arrow functions cannot be used as constructors. Single-expression functions implicitly return the value. Multi-line bodies require braces and explicit return. They are ideal for callbacks and functional programming.
Closures
A closure is a function that retains access to variables from its enclosing scope even after the outer function has returned. Example: function outer() { let count = 0; return function inner() { count++; return count; }; }. The inner function closes over count. Closures enable data privacy, function factories, and partial application. They are essential for modules, callbacks, and maintaining state.
Immediately Invoked Function Expressions (IIFE)
IIFEs are functions that run immediately after definition. Syntax: (function() { /* code */ })(). They create a new scope, preventing variable pollution. Useful for initialization, encapsulation, and avoiding naming conflicts. Example: (function() { const private = 'secret'; console.log(private); })(). IIFE with arrow: (() => console.log('arrow'))(). Common in modular patterns before ES6 modules.
The `this` Keyword
this refers to the object that owns the current function execution context. In global scope, it's the global object (window in browsers). In object methods, it's the object. In functions, it depends on how the function is called. Arrow functions inherit this from outer scope. Issues arise when callbacks lose context. this is determined at call time, not definition time, which is crucial for understanding JavaScript.
call, apply, and bind
call() invokes a function with a given this and arguments passed individually. Example: func.call(context, arg1, arg2). apply() is similar but takes arguments as an array. bind() returns a new function with this permanently bound. Example: const bound = func.bind(context). Essential for callback functions where this needs to be controlled. Used in method borrowing, currying, and maintaining context in asynchronous code.
Higher-Order Functions
Higher-order functions take functions as arguments, return functions, or both. Examples: Array.map(), filter(), reduce() are higher-order functions. Custom example: function repeat(n, action) { for (let i = 0; i < n; i++) action(i); }. They enable composition, abstraction, and functional programming patterns. Used extensively in event handling, promises, and array manipulations.
Quiz
1. What is the main focus of Functions & Closures?
2. Which keyword is used to define a function declaration in JavaScript?
3. What does a closure capture from its enclosing scope?
Flashcards
Question
What is Functions & Closures?
Click to reveal answer
Answer
Functions & Closures covers function declarations, expressions, arrow functions, closures, the this keyword, call/apply/bind, and higher-order functions.
Question
What is a closure in JavaScript?
Click to reveal answer
Answer
A closure is a function that retains access to variables from its outer lexical scope even after the outer function has finished executing.
Question
How do arrow functions differ from regular functions?
Click to reveal answer
Answer
Arrow functions have no own `this`, `arguments`, or `super` bindings. They inherit `this` from the enclosing scope and cannot be used as constructors.
Revision Notes
Key Takeaways
- 1. Functions are first-class objects in JavaScript, enabling powerful patterns like callbacks and closures
- 2. Closures allow functions to remember their creation environment, enabling data privacy and state management
- 3. `this` is determined at call time; arrow functions inherit `this` from their outer scope
- 4. Higher-order functions enable functional programming and code composition
Interview Tips
- • Explain the difference between function declarations and expressions, highlighting hoisting
- • Describe how closures work and give practical examples like data privacy or function factories
- • Discuss the `this` keyword binding rules and common pitfalls in callbacks
- • Compare call, apply, and bind methods with use cases
Cheat Sheet
Functions: declarations (hoisted), expressions (assigned), arrow (lexical this). Closures: retain outer scope variables. this: depends on call context. call/apply/bind: control this. Higher-order: take/return functions.