1. Invocation Function trong JavaScript là gì?

Trong tiếng anh, có một vài từ liên quan đến việc gọi hàm như: call a function, invoke a function, execute a function . Trong Js ta có invoke (hay là invocation nếu là danh từ). Nó có ngụ ý là hàm sẽ tự động thực thi mà không cần gọi (ví dụ hàm constructor sẽ tự động thực thi khi một function object được tạo). Ta sẽ thường biết đến “call a function” thay vì “invoke a function” . 

Trong gọi hàm, có hai thành phần quan trọng là từ khoá this và các đối số (arguments). This được hiểu tuỳ theo cách gọi một hàm. Có 4 cách gọi một hàm là gọi hàm như một phương thức, gọi hàm như một hàm, gọi hàm bằng hàm constructor và gọi hàm với phương thức applycall . Một giá trị của đối số là một giá trị chúng ta sẽ gán đến tên của một tham số của một hàm.

2. Gọi một hàm dưới dạng một phương thức

Khi một hàm là một thành phần của một object thì hàm được gọi là phương thức (method), ví dụ phương thức fullName được định nghĩa trong đối tượng myObject :

<script>
const myObject = {
  firstName:"Thành",
  lastName: "Nguyễn",
  fullName: function() {
    return this.firstName + " " + this.lastName;
  }
}
document.write(myObject.fullName()); 
</script>

Trong ví dụ trên, từ khoá this dùng để chỉ chính đối tượng myObject . Khi gọi phương thức fullName , không có giá trị argument nào vì khi định nghĩa fullName trong myObject không có tham số.

Ta có thể thay đổi phương thức fullName để trả về giá trị của this

<script>
const myObject = {
  firstName:"Thành",
  lastName: "Nguyễn",
  fullName: function() {
    return this;
  }
}
document.write(myObject.fullName());
</script>

Gọi một hàm như một phương thức đối tượng, khiến giá trị của chính this là đối tượng.

3. Gọi một hàm dưới dạng một hàm

Khi hàm không là một phần của đối tượng, nó được xem là một hàm. Ví dụ khai báo hàm Add và gán giá trị trả về của nó cho một biến:

function Add (a, b) // a, b là các tham số
 
{
 
  return a+b;
 
}
 
var sum = Add (3, 4);
 
document.write(sum);

Lúc này this sẽ trở thành một đối tượng toàn cục (global object). Trong trình duyệt web, đối tượng toàn cục sẽ là cửa sổ trình duyệt hay đối tượng Window . Chúng ta có thể kiểm tra điều này một cách dễ dàng như ví dụ dưới đây:

function myObject ()
 
{
 
  return this;
 
}
 
// kết quả khi gọi hàm là [object Window]
 
document.write(myObject());

Vì this là một đối tượng toàn cục nên đôi khi dẫn tới trường hợp là một phương thức sẽ không thể dùng this trong hàm bên trong nó (inner function). Ta có thể gán giá trị của this cho một biến và hàm trong phương thức sẽ truy cập this thông qua biến này.

Ví dụ:

var ob = {
 
   x:3,
 
   y:4,
 
   add: function()
 
  {
 
   var that = this;
 
   function aa()
 
   {
 
    return that.x + that.y;
 
   }
 
   return aa();
 
  } 
 
}
 
document.write(ob.add());// kết quả là 7

Lưu ý

Đây là một cách phổ biến để gọi một hàm JavaScript, nhưng không phải là một cách thực hành tốt. Các biến, phương thức hoặc hàm toàn cục có thể dễ dàng tạo ra xung đột tên và lỗi trong đối tượng toàn cục.

Gọi một hàm dưới dạng một hàm toàn cục, làm cho giá trị của hàm này là đối tượng toàn cục. Việc sử dụng đối tượng window như một biến có thể dễ dàng làm hỏng chương trình của ta.

4. Gọi hàm với một hàm tạo

Khi một hàm được gọi với từ khoá new , hàm constructor sẽ được gọi. Vì hàm là một đối tượng trong Js nên hàm constructor là một đối tượng. Gọi hàm với new là tạo một đối tượng mới và đối tượng mới này thừa kế tất cả thuộc tính và phương thức của hàm constructor .

Ví dụ:

<script>
function myFunction(arg1, arg2) {
  this.firstName = arg1;
  this.lastName  = arg2;
}

const myObj = new myFunction("Thành","Nguyễn")
document.write(myObj.firstName); 
</script>

Đối tượng mới được tạo ra sẽ liên kết đến tất cả các giá trị của thành viên prototype của hàm , từ khoá this sẽ trở thành đối tượng mới đó. Từ khóa this trong hàm tạo không có giá trị. Giá trị của this luôn là đối tượng mới được tạo khi hàm được gọi.

5. Gọi hàm với phương thức call và apply

Vì hàm là đối tượng nên nó cũng chứa các phương thức. Hai phương thức dùng để gọi hàm (gọi chính nó) là callapply . Hai phương thức cùng có đối số (argument) đầu tiên là giá trị của this (đối tượng hay null) và các đối số còn lại của call cách nhau bởi dấu phẩy, trong khi các đối số còn lại của apply được tổ chức trong một mảng.

Ví dụ:

Với Call

function Add (a, b) // a, b là các tham số
 
{
 
  return a+b;
 
}
 
var ob = Add.call (ob, 3, 4);
 
document.write(ob);

Với Apply

function Add (a, b) // a, b là các tham số
 
{
 
  return a+b;
 
}
 
var arr = [3, 4];
 
var ob = Add.apply (ob, arr);
 
document.write(ob);