Function Hoisting
Function declarations in JavaScript are hoisted to the top of their lexical scope, allowing them to be invoked before they are defined. This behavier offers greater flexibility in function placement.
- Function expressions do not exhibit hoisting
- Hoisting occurs strictly within the same scope
Example:
calculateTotal()
function calculateTotal() {
console.log('Hoisted function executed')
}
Function Parameters
Dynamic Parameters
arguments is a built-in pseudo-array variable accessible inside all non-arrow functions. It contains every argument pased to the function when it was called.
Example:
function sumAllNumbers() {
let total = 0
for (let index = 0; index < arguments.length; index++) {
total += arguments[index]
}
console.log(`Total sum: ${total}`)
}
sumAllNumbers(2, 4, 6)
sumAllNumbers(1, 3, 5, 7, 9)
Rest Parameters
Rest parameters use the ... syntax to collect an indefinite number of additional arguments into a real array. They must be placed as the last parameter of a function signature.
Example:
function calculateProduct(basePrice, ...discounts) {
let finalPrice = basePrice
for (const discount of discounts) {
finalPrice *= (1 - discount)
}
return finalPrice
}
console.log(calculateProduct(100, 0.1, 0.05)) // 94.5
Rest properties can also terminate destructuring patterns, collecting all remaining properties of an object or array into new containers.
Destructuring examples:
const { id, ...productDetails } = { id: 101, name: 'Wireless Headphones', price: 299 }
console.log(productDetails) // { name: 'Wireless Headphones', price: 299 }
const [firstItem, ...remainingCart] = ['Keyboard', 'Mouse', 'Monitor']
console.log(remainingCart) // ['Mouse', 'Monitor']
Spread Operator
The spread operator (...) expands iterable values (like arrays or strings) into individual elements or properties. It does not modify the original iterable.
Examples:
const initialCart = ['Laptop', 'Charger']
const additionalItems = ['Mouse', 'Keyboard']
const fullCart = [...initialCart, ...additionalItems]
console.log(fullCart) // ['Laptop', 'Charger', 'Mouse', 'Keyboard']
const defaultSettings = { theme: 'light', notifications: true }
const userSettings = { theme: 'dark', language: 'en-US' }
const mergedSettings = { ...defaultSettings, ...userSettings }
console.log(mergedSettings) // { theme: 'dark', notifications: true, language: 'en-US' }
Arrow Functions
Arow functions are concise alternatives to traditional function expressions, ideal for anonymous function scenarios.
Basic Syntax
- Syntax 1 (No parameters): Wrap an empty parameter list in parentheses
- Syntax 2 (Single parameter): Omit parentheses around the single parameter
- Syntax 3 (Single-line return): Omit curly braces and the
returnkeyword - Syntax 4 (Returning an object literal): Wrap the object in parentheses to avoid ambiguity with function blocks
Examples:
// No parameters
const logCurrentTime = () => {
console.log(new Date().toLocaleString())
}
// Single parameter
const doubleValue = num => num * 2
// Single-line return
const addNumbers = (x, y) => x + y
// Returning an object literal
const createUserProfile = name => ({ username: name, createdAt: new Date() })
Parameters in Arrow Functions
Arrow functions do NOT have built-in dynamic arguments pseudo-arrays, but they fully support rest parameters for collecting additional arguments.
Example:
const calculateAverage = (...scores) => {
const total = scores.reduce((sum, score) => sum + score, 0)
return total / scores.length
}
console.log(calculateAverage(85, 90, 92)) // 89
this in Arrow Functions
Arrow functions do not create their own this context. Instead, they inherit this from the lexical scope immediately above them.
Examples:
// Global scope arrow function
const showGlobalContext = () => {
console.log(this) // Points to window
}
showGlobalContext()
// Object method as a traditional function
const user = {
username: 'Alex',
logWelcomeMessage: function() {
console.log(`Welcome, ${this.username}!`) // Points to user
const countdown = () => {
console.log(`Redirecting in 3 seconds, ${this.username}`) // Inherits from logWelcomeMessage, points to user
}
countdown()
}
}
user.logWelcomeMessage()
// DOM event listener (NOT recommended)
const button = document.createElement('button')
button.textContent = 'Click Me'
button.addEventListener('click', () => {
console.log(this) // Points to window, not the button
})