IIFE trong javascript là gì?

Jun 28, 2021 • ngocnhan2003

iife.png

IIFE là viết tắt của Immediately Invoked Function Expression, có nghĩa là khởi tạo một function và thực thi nó ngay lập tức. Cú pháp của IIFE là:

(function(){
 //code here
})();

Ta có thể truyền tham số cho IIFE như sau:

(function(window, name){
 //code here
})(window, name);

Vậy tại sao lại dùng IIFE? Bởi vì IIFE như là một các hộp đóng gói code của chính nó. Do đó, những biến trong hộp này là private, bên ngoài(global) không thể truy xuất hay thay đổi được. Và nếu vô tình bạn đặt tên biến giống với global thì cũng không bị ảnh hưởng bên ngoài.

Xem ví dụ sau nhé:

var greeting = "Hola";
var name = "Thau";

(function (window, name) {
  //code here
  var greeting = "Hello";
  console.log(greeting + " " + name);
})(window, name);

Bạn có thể thấy rằng ta có hai biến greeting. Một là toàn cục, một trong IIFE. Hai biến này nằm ở hai contextbộ nhớ khác nhau, nên khi ta thay đổi biến greeting trong IIFE không làm ảnh hưởng greeting ở ngoài và ngược lại.

Có một điều lưu ý là khi tạo thư viện bằng khối IIFE thì bạn nên sử dụng ‘use strict’ để tránh được một số lỗi về type, scope trong js. Nếu như ví dụ trên nếu không có strict mode như sau:

var greeting = "Hola";
var name = "Thau";
(function (window, name) {
  //code here
  greeting = "Hello";
  console.log(greeting + " " + name);
})(window, name);

Biến greeting ở đây vô tình là global và sẽ thay đổi luôn giá trị của biến bên ngoài. Cho nên để hạn chế điều này bạn có thể sử dụng strict mode.

(function (window, name) {
  //code here
  "use strict";
  greeting = "Hello";
  console.log(greeting + " " + name);
})(window, name);
//  Ở đoạn code này JS sẽ throw error vì bạn đang cố truy cập một biến gobal trong IIFE

Cùng xem một ví dụ khác:

for (var i = 0; i < 10; i++) {
  setTimeout(function () {
    console.log(i); //biến i ở đây là biến i của for
  });
}

setTimeout sẽ chạy khi vòng for chạy xong, do đó i = 10;

for (var i = 0; i < 10; i++) {
  (function (i) {
    //IIFE tạo ra một scope khác cho từng i, nên giá trị của i là khác nhau
    setTimeout(function () {
      console.log(i);
    });
  })(i); //biến i ở đây được tạo riêng cho từng IIFE
}

Mỗi vòng lặp IIFE tạo một scope mới cho i, nên i ở đây là khác nhau.

Tóm lại, IIFE hữu ích khi chúng ta muốn đóng gói code để nó không ảnh hưởng đến các biến toàn cục. Nó hữu ích khi chúng ta viết những thư viện. Sau đó, chúng ta nhúng vào những trang web khác nhau thì cũng không ảnh hưởng đến code của chúng ta.