Javascript's Apply, Call and Bind

Chắc có thể mọi người đã biết rồi, hàm (function) trong Javascript cũng được coi là những đối tượng (object). Vậy thì sao? Trả lời: Bản thân hàm cũng sẽ có những phương thức được gắn với nó, kiểu như phương thức gắn với đối tượng vậy đó. Điều này là một trong điều khiến Javascript trở thành ngôn ngữ kì dị, kì lạ kì cục nhất trên cõi đời này. Có thể kể đến những phương thức gắn liền với hàm như: Apply(), Call() và Bind().

> Call và Apply

Phương thức call() và apply() để gọi thực thi một hàm với một ngữ cảnh chỉ định thông qua tham số thisArg và các tham số đầu vào của hàm tương ứng. Tức là nó sẽ cho phép hàm thực thi được với một ngữ cảnh chỉ định nào đó tuỳ ý. Sự khác nhau giữa chúng là call() sẽ nhận tham số hàm qua từng biến đầu vào riêng biệt còn apply() thì lại nhận các tham số hàm qua một mảng chứa các biến đầu vào. Ta cùng xét ví dụ bên dưới:

var obj = {
    firstName: "Vô",
    lastName : "Danh",
 
    mMethod: function(firstName, lastName) {
        var firstName = firstName || this.firstName
        var lastName = lastName || this.lastName
        console.log("Hello " + firstName + " " + lastName)
    }
}
 
var obj1 = {
    firstName: "Ông",
    lastName : "Ké"
};
 
obj.mMethod() // Hello Vô Danh
 
obj.mMethod.call(obj1) // Hello Ông Ké
 
obj.mMethod.apply(obj1) // Hello Ông Ké
 
obj.mMethod.call(obj1, "Thị", "Nở") // Hello Thị Nở
 
obj.mMethod.apply(obj1, ["Chí", "Phèo"]) // Hello Chí Phèo

Với đoạn mã trên ta có thể thấy rằng, sau khi gọi call() hoặc apply() ngữ cảnh thực thi của mMethod đã được đổi sang obj1 và call() cho phép ta truyền tham số đầu vào riêng biệt còn apply() lại cho phép truyền vào như một mảng.

Từ phiên bản 5, apply() còn có thể được truyền vào một đối tượng tựa mảng (chú thích [1]) thay vì mảng:

var obj = {
    firstName: "Vô",
    lastName : "Danh",
 
    mMethod: function(firstName, lastName) {
        var firstName = firstName || this.firstName
        var lastName = lastName || this.lastName
        console.log("Hello " + firstName + " " + lastName)
    }
}
 
var obj1 = {
    firstName: "Ông",
    lastName : "Ké"
};
 
obj.mMethod.apply(obj1, ["Chí", "Phèo"]) // Hello Chí Phèo
 
obj.mMethod.apply(obj1, {'length': 2, '0': "Chí", '1': "Phèo"}) // Hello Chí Phèo

All Rights Reserved