JS Functions
Functions Advanced
This page covers advanced JavaScript function concepts: definitions, callbacks, this, call/apply/bind, IIFE, closures, and common patterns you will see in real projects.
Function Definitions
JavaScript supports multiple ways to define functions: declarations, expressions, arrow functions, and generator functions.
// Function declaration (hoisted)
function add(a, b) {
return a + b;
}
// Function expression
const multiply = function (a, b) {
return a * b;
};
// Arrow function
const square = (n) => n * n;
// Generator function
function* ids() {
let n = 1;
while (true) yield n++;
}
Function Callback
A callback is a function passed into another function. Callbacks are used everywhere: events, async operations, array methods.
function runTask(task) {
task();
}
runTask(() => {
console.log("Task done");
});
Common callback usage with array methods:
const nums = [1, 2, 3, 4]; const doubled = nums.map((n) => n * 2); const big = nums.filter((n) => n > 2); console.log(doubled); console.log(big);
Function this
this depends on how a function is called. In methods, this usually refers to the object before the dot.
const user = {
name: "Ozan",
greet() {
console.log("Hello, " + this.name);
}
};
user.greet(); // this => user
If you extract a method and call it without an object, this can change (often undefined in strict mode).
"use strict";
const obj = {
value: 10,
show() {
console.log(this.value);
}
};
const fn = obj.show;
// fn(); // TypeError (this is undefined in strict mode)
Arrow functions do not have their own this. They capture this from the surrounding scope.
const team = {
name: "W4",
members: ["A", "B"],
print() {
this.members.forEach((m) => {
console.log(this.name + " - " + m);
});
}
};
team.print();
Function Call
call() invokes a function and sets this explicitly. Arguments are passed one by one.
function intro(city) {
console.log(this.name + " from " + city);
}
const person = { name: "Jane" };
intro.call(person, "Istanbul");
Function Apply
apply() is like call(), but arguments are passed as an array.
function sum(a, b, c) {
return a + b + c;
}
const result = sum.apply(null, [1, 2, 3]);
console.log(result);
Function Bind
bind() returns a new function with a fixed this value. It does not call the function immediately.
const account = {
owner: "Ozan",
show() {
console.log("Owner: " + this.owner);
}
};
const showLater = account.show.bind(account);
showLater();
Bind is useful in event handlers when you need stable this.
const counter = {
value: 0,
inc() {
this.value++;
console.log(this.value);
}
};
// Example idea:
// button.addEventListener("click", counter.inc.bind(counter));
Function IIFE
An IIFE (Immediately Invoked Function Expression) runs once immediately. It is used for scoping and initialization.
(function () {
const secret = "hidden";
console.log("Init done");
})();
Modern note: ES modules already create their own scope, so IIFE is less common today, but you will still see it in older code.
Function Closures
A closure happens when a function remembers variables from its outer scope, even after the outer function finishes.
function makeCounter() {
let count = 0;
return function () {
count++;
return count;
};
}
const c1 = makeCounter();
console.log(c1()); // 1
console.log(c1()); // 2
const c2 = makeCounter();
console.log(c2()); // 1
Closures are used for private state, factories, and memoization.
function memoAdd() {
const cache = new Map();
return function (n) {
if (cache.has(n)) return cache.get(n);
const v = n + 10;
cache.set(n, v);
return v;
};
}
const f = memoAdd();
console.log(f(5));
console.log(f(5));
Function Reference
Key function topics you should know:
- Declaration vs expression vs arrow
- Parameters: default and rest (
...args) thisrules and arrow functionscall,apply,bind- IIFE patterns
- Closures
Function Quiz
Try to predict the output before running the code.
// 1) What is printed?
let x = 1;
function test() {
let x = 2;
return function () {
console.log(x);
};
}
test()(); // ?
// 2) call vs bind
function show() {
console.log(this.name);
}
const p = { name: "Ali" };
show.call(p); // ?
const bound = show.bind(p);
bound(); // ?
// 3) this in arrow
const obj2 = {
name: "W4",
run() {
const fn = () => console.log(this.name);
fn();
}
};
obj2.run(); // ?
Next Step
Continue with JS Objects (Advanced) or JS Classes to learn modern OOP patterns.