Series về ES6: IIFE, Closure

Series về ES6: IIFE, Closure

Trong phần trước thì chúng ta đã đi tìm hiểu về Class. Trong phần tiếp theo, chúng ta sẽ đi tìm hiểu về IIFE và Closure.

  • IIFE
  • Closure
  • Ví dụ
  1. IIFE

IIFE là viết tắt của Immediately Invoked Function Expression. IIFE là một function của Javascript, function này chạy ngay khi nó được định nghĩa

IIFE khác với chức năng truyền thống mà chúng ta có thể gọi nó nhiều lần những IIFE thì không. Nó chỉ sử dụng một lần nên các biến trong hàm là bất biến.

Một trong những lợi ích của IIFE là tạo phạm vi cục bộ và điều này rất quan trong nếu có nhiều file thư mục cùng tên biến. Do vậy nên IIFE tránh ghi đè và bảo vệ phạm  vi của các biến đó

Có hai cách để gọi hàm:

  • Đầu tiên, cách truyền thống của chúng ta để xác định và gọi hàm
function printName(){
  let myName = "Mohamed"
  console.log(myName)
}
//Invoke
printName()
  • Thứ hai, Sử dụng IIFE. Chúng ta đặt hàm của chúng ta trong dấu ngoặc, sau đó chúng ta thêm một cặp dấu ngoặc vào cuối hàm
(function printName(){
  let myName = "Mohamed"
  console.log(myName)
})()

Trên thực tế, chúng ta không cần đặt tên cho hàm vì nó chỉ được gọi một lần. Vì vậy IIFE thường sẽ là chức năng ẩn danh

(function(){
  let myName = "Mohamed"
  console.log(myName)
})()

Truyền tham số và đối số vào trong một IIFE

(function myName(name) {
    console.log("name: ", name)
})("Mohamed")
//name: Mohamed

Lưu ý : Sử dụng dấu ; trước một hàm IIFE tránh gây ra lỗi xảy ra khi gọi một hàm trên một toán tử không phải là hàm.

let name="Mohamed"
(function(){
    console.log("Name")
})() // Error: Mohamed is not a function
let name="Mohamed"
;(function(){
    console.log("Name")
})() // Name

IIFE là một hàm private tức là bạn sẽ không thể lấy và gọi hàm bên trong IIFE ra ngoài cũng như các biến được khai báo bên trong IIFE.

(function myName(){
    console.log("Name")
})()
myName() // Error: myName is not defined

Hàm trong IIFE chỉ được sử dụng lại trong trường hợp chúng ta sử dụng đệ quy trong chính IIFE đó.

(function myName(){
    console.log("Name")
    if(điều kiện dừng)
        myName()
})()

2. Closure

Closures là khi một hàm ghi nhớ lexical scope ngay cả khi 1 hàm được thực hiện bên ngoài lexical scope. Vì vậy closure là khi 1 function sử dụng 1 biến được định nghĩa trong 1 function khác hoặc 1 scope khác. Nó tạo ra một liên kết tới biến này để cập nhật biến của nó

Ví dụ, chúng ta có 1 function printName có 1 biến. Sau đó chúng ta có 1 function closure gọi function print. Cuối cùng, chúng ta gọi function này trong 1 scope khác.

Nói cách khác, Chúng ta thực hiện function print sử dụng 1 biến name. Biến này không được khai báo ở trong scope function closure, Nhưng biến này vẫn nằm trong scope function printName

Mặc định thì logic này là sai. Nhưng thực tế thì đây là 1 closure. Vì vậy nếu chúng ta thay đổi, cập nhật giá trị tên biến của chúng ta, Closure sẽ cập nhật nó

function printName(){
   let name="Truyen";
   function print() {
      console.log(name);
   }

   closure(print);
}

function closure(func)
{    
    func();
}

printName();

Ví dụ khác, chúng ta có thể lấy hoặc cập nhật biến x trong inner function

function outer(){
  let x = 4
  function inner (){
    let y = x
    y = 16
    console.log(x)
    console.log(x*2)
    console.log(y)
  }

  closure(inner);  
}

function closure(inn)
{    
    inn();
}

outer()

Đây là một cách khác để nạp function closure ở trước. Ở đậy chúng ta đã thay thế một inner function là 1 anonymous function là hàm này trả về nhiều giá trị trong 1 mảng. Sau đó chúng ta đã thực hiện outer function.

3 Ví dụ

Khi chỉ sử dụng Closure kết hợp với IIFEs.

function celebrityIDCreator (theCelebrities) {
	var i;
	var uniqueID = 100;
	for (i = 0; i < theCelebrities.length; i++) {
		theCelebrities[i]["id"] = function (j)  { 
			return function () {
				return uniqueID + j; 
			}();
		} (i);
	}
	return theCelebrities;
}

const actionCelebs = [
    {name:"Stallone", id:0}, 
    {name:"Cruise", id:0}, 
    {name:"Willis", id:0}
  ];

const createIdForActionCelebs = celebrityIDCreator (actionCelebs);

const stalloneID = createIdForActionCelebs [0];
console.log(stalloneID); // 100

Trong bài viết này chúng ta đi tìm hiểu về IIFEs và Closure, cách sử dụng của nó có thể tái sử dụng những đoạn code khi thực hiện cùng một chức năng. Nhưng chia sẻ này hi vọng có ích cho các bạn tìm hiểu về javascript và ES6. Trong phần tiếp theo, chúng ta sẽ đi tìm hiểu về bất đồng bộ trong Javascript.

Tài liệu tham khảo

https://dev.to/this_mkhy_dev/do-you-know-es6-part-3-advanced-3fcl
https://viblo.asia/p/es6-tu-co-ban-toi-nang-cao-phan-3-6J3ZgxELlmB

Xem tiếp phần tiếp theo của series tại đây.

hoặc tham khảo phần trước của series tại đây.