apply() gọi hàm ngay lập tức với this chỉ định và arguments dưới dạng mảng (array-like). Khác với call() nhận danh sách tham số rời rạc.
Cú pháp
fn.apply(thisArg, [argsArray]);
apply() vs call()
function multiply(a, b, c) {
return this.num * a * b * c;
}
const obj = { num: 10 };
const args = [6, 3, 4];
// call() — arguments rời rạc
multiply.call(obj, 6, 3, 4); // 720
// apply() — arguments array
multiply.apply(obj, args); // 720 — hữu ích khi args đã là mảng
// call() với array → SAI
multiply.call(obj, args); // NaN — obj.num * [6,3,4] * undefined * undefined
Use Case Phổ Biến
1. Gọi hàm với mảng arguments động
function sum(...numbers) {
return numbers.reduce((a, b) => a + b, 0);
}
const values = [1, 2, 3, 4, 5];
sum.apply(null, values); // 15
// ES6: sum(...values) — spread operator thay thế apply()
2. Mượn method (Method Borrowing)
const arrayLike = { 0: 'a', 1: 'b', length: 2 };
const arr = Array.prototype.slice.apply(arrayLike); // ['a', 'b']
// ES6: Array.from(arrayLike) hoặc [...arrayLike]
3. Math.max/min với mảng
const numbers = [5, 2, 9, 1, 7];
Math.max.apply(null, numbers); // 9
// ES6: Math.max(...numbers) — spread operator
4. Constructor với array arguments (ES5)
function Person(name, age) {
this.name = name;
this.age = age;
}
const args = ['Alice', 30];
const person = new (Person.bind.apply(Person, [null, ...args]))();
// ES6: new Person(...args)
Lưu ý
apply()nhận array-like object (có length và indexed property) — không nhất thiết là Array.- ES6 spread operator (
...) thay thế hầu hết use case củaapply()— ngắn gọn, nhanh hơn, dễ đọc. nullhoặcundefinedlàmthisArg→ this = global (non-strict) hoặc undefined (strict).
So sánh nhanh
| call() | apply() | bind() | |
|---|---|---|---|
| Gọi ngay? | Có | Có | Không (trả về fn mới) |
| Arguments | Rời rạc (a, b, c) | Mảng/array-like | Preset + gọi sau |
| Trả về | Kết quả fn | Kết quả fn | Hàm mới |
| ES6 thay thế | fn(...args) | fn(...args) | Arrow function / bind |