8.1 Phương thức call
Các phương thức call, bind và apply trong JavaScript đóng vai trò quan trọng trong việc điều khiển ngữ cảnh thực thi của hàm, cho phép thiết lập giá trị this khi gọi hàm. Những phương thức này đặc biệt hữu ích khi làm việc với đối tượng và lập trình hàm, cung cấp công cụ mạnh mẽ để quản lý linh hoạt mã. Hãy xem xét từng cái một cách chi tiết hơn và phân tích các ví dụ sử dụng của chúng.
Phương thức call gọi hàm với giá trị this đã cho và các tham số truyền vào qua dấu phẩy. Điều này cho phép chúng ta chỉ định rõ ràng ngữ cảnh mà hàm nên thực thi.
Cú pháp:
func.call(thisArg, arg1, arg2 ...);
Ví dụ:
Trong ví dụ này, hàm greet được gọi với ngữ cảnh person, cho phép nó sử dụng thuộc tính name của đối tượng person.
function greet(greeting, punctuation) {
console.log(greeting + ', ' + this.name + punctuation);
}
const person = { name: 'John' };
greet.call(person, 'Hello', '!'); // Output: Hello, John!
8.2 Phương thức apply
Phương thức apply tương tự như call, nhưng truyền tham số dưới dạng mảng. Điều này tiện lợi khi chúng ta có một mảng tham số mà muốn truyền cho hàm.
Cú pháp:
func.apply(thisArg, [argsArray]);
Ví dụ:
Ví dụ này tương tự như ví dụ trước, nhưng tham số được truyền dưới dạng mảng.
function greet(greeting, punctuation) {
console.log(greeting + ', ' + this.name + punctuation);
}
const person = { name: 'John' };
greet.apply(person, ['Hello', '!']); // Output: Hello, John!
8.3 Phương thức bind
Phương thức bind tạo một hàm mới mà khi được gọi sẽ thiết lập giá trị this đã cho trước. Tham số truyền vào bind được cố định trong hàm mới. Điều này cho phép tạo ra các hàm với ngữ cảnh cố định.
Cú pháp:
const boundFunc = func.bind(thisArg, arg1, arg2 ...);
Ví dụ:
Trong ví dụ này, một hàm mới boundGreet được tạo ra, mà luôn được thực thi trong ngữ cảnh của đối tượng person.
function greet(greeting, punctuation) {
console.log(greeting + ', ' + this.name + punctuation);
}
const person = { name: 'John' };
const boundGreet = greet.bind(person, 'Hello');
boundGreet('!'); // Output: Hello, John!
8.4 Phân tích chi tiết việc sử dụng các phương thức
1. Sử dụng call để thừa kế phương thức:
Phương thức call thường được dùng để thừa kế phương thức của một đối tượng khác. Điều này cho phép mượn phương thức và thuộc tính mà không cần thừa kế rõ ràng.
Trong ví dụ này, constructor Product được gọi trong ngữ cảnh của đối tượng Food, cho phép thừa kế thuộc tính name và price.
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price, category) {
Product.call(this, name, price);
this.category = category;
}
const cheese = new Food('Cheese', 5, 'Dairy');
console.log(cheese); // Output: Food { name: 'Cheese', price: 5, category: 'Dairy' }
2. Sử dụng apply để truyền mảng tham số:
Phương thức apply tiện lợi khi ta muốn truyền một mảng tham số cho một hàm chấp nhận các tham số riêng biệt.
Trong trường hợp này, mảng numbers được truyền cho hàm sum như các tham số riêng biệt.
function sum(a, b, c) {
return a + b + c;
}
const numbers = [1, 2, 3];
console.log(sum.apply(null, numbers)); // Output: 6
3. Sử dụng bind để tạo hàm với ngữ cảnh cố định:
Phương thức bind cho phép tạo hàm với ngữ cảnh cố định, điều này đặc biệt hữu ích khi làm việc với sự kiện và callback.
Ở đây hàm getX được gắn với đối tượng module bằng cách sử dụng bind, điều này cho phép lấy giá trị x một cách chính xác khi gọi hàm.
const module = {
x: 42,
getX: function() {
return this.x;
}
};
const unboundGetX = module.getX;
console.log(unboundGetX()); // Output: undefined
const boundGetX = unboundGetX.bind(module);
console.log(boundGetX()); // Output: 42
8.5 Ví dụ từ thực tế
Ví dụ dùng call để mượn phương thức của mảng:
Trong ví dụ này, phương thức forEach của mảng được sử dụng cho đối tượng arguments bằng cách dùng call.
function printArguments() {
Array.prototype.forEach.call(arguments, function(item) {
console.log(item);
});
}
printArguments(1, 2, 3); // Output: 1, 2, 3
Ví dụ dùng apply để nối các mảng:
Ở đây, phương thức push được sử dụng để nối hai mảng bằng cách dùng apply.
const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
Array.prototype.push.apply(array1, array2);
console.log(array1); // Output: [1, 2, 3, 4, 5, 6]
Ví dụ dùng bind để tạo hàm một phần:
Hàm double được tạo với tham số đầu tiên cố định là 2 bằng cách sử dụng bind.
function multiply(a, b) {
return a * b;
}
const double = multiply.bind(null, 2);
console.log(double(5)); // Output: 10
GO TO FULL VERSION