Phương thức Function.prototype.call() cho phép gọi một hàm với giá trị this xác định và truyền các đối số riêng lẻ (khác với apply() nhận mảng).
Cú pháp
func.call(thisArg, arg1, arg2, ...)
thisArg: Giá trịthisbên trong hàm.arg1, arg2...: Các đối số truyền cho hàm.
Ví dụ: Mượn phương thức giữa các đối tượng
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>JavaScript call() Method</title>
<style>
body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; max-width: 600px; margin: 2rem auto; padding: 0 1rem; }
.sample { font-size: 1.2rem; font-weight: 500; margin: 1rem 0; }
button { padding: 0.5rem 1rem; background: #20c997; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 1rem; }
button:hover { background: #1aa179; }
</style>
</head>
<body>
<h1>Phương thức call() trong JavaScript</h1>
<div class="sample" id="sampleEl"></div>
<button id="btn">KIỂM TRA NGƯỜI LỚN</button>
<p>Nhấn nút để gọi checkAdult() với object obj1 qua call()</p>
<script>
const sampleEl = document.getElementById('sampleEl');
// Đối tượng người dùng
const user = { name: "Rohan", age: 22 };
// Hàm chung - dùng this.age, this.name
function checkAdult(vehicle, country) {
if (this.age >= 18) {
sampleEl.textContent = `${this.name}, bạn đã trưởng thành và có thể lái ${vehicle} tại ${country}.`;
} else {
sampleEl.textContent = `${this.name}, bạn CHƯA trưởng thành, không thể lái ${vehicle} tại ${country}.`;
}
}
document.getElementById('btn').addEventListener('click', () => {
// Gọi checkAdult với this = user, truyền 2 đối số riêng lẻ
checkAdult.call(user, 'ô tô', 'Việt Nam');
});
</script>
</body>
</html>
Kết quả
Ban đầu: Trống.
Sau khi nhấn nút:
Rohan, bạn đã trưởng thành và có thể lái ô tô tại Việt Nam.
So sánh: call() vs apply() vs bind()
| Phương thức | Đối số | Thực thi ngay | Trả về |
|---|---|---|---|
call(this, a, b) | Rõ ràng, riêng lẻ | Có | Kết quả hàm |
apply(this, [a,b]) | Mảng/array-like | Có | Kết quả hàm |
bind(this, a, b) | Rõ ràng/riêng lẻ | Không (trả về hàm mới) | Hàm mới |
Các trường hợp sử dụng phổ biến
1. Mượn phương thức mảng cho array-like object
const args = { 0: 'a', 1: 'b', length: 2 };
const arr = Array.prototype.slice.call(args); // ['a', 'b']
// Hoặc ES6: const arr = [...args];
2. Chaining constructor (Kế thừa)
function Animal(name) {
this.name = name;
}
function Dog(name, breed) {
Animal.call(this, name); // Gọi constructor cha
this.breed = breed;
}
3. Gán this cho callback/event handler
const obj = { value: 42 };
setTimeout(function() {
console.log(this.value); // 42
}.call(obj), 1000);
Lưu ý
- Trong strict mode,
thisArgđược truyền chính xác (có thể lànull,undefined, primitive). - Trong non-strict mode,
null/undefinedđược thay bằngglobalThis, primitive được wrap thành object. call()hữu ích khi muốn tái sử dụng logic mà không cần kế thừa hoặc copy code.