Closures trong JavaScript

Chào các bạn,

Trong bài này mình sẽ giới thiệu về closures trong JavaScript

  • Closure là 1 tính năng mạnh mẽ của JavaScript.
  • JavaScript cho phép nhóm các chức năng và cấp cho hàm bên trong truy cập đầy đủ tới tất cả các biến bên trong truy cập đầy đủ tới tất cả các biến và hàm được xác định bên trong của hàm bên ngoài ( tất các các biến và hàm khác mà hàm bên ngoài có quyền truy cập vào). Tuy nhiên thì hàm ngoài không có quyền truy cập vào các biến và hàm được định nghĩa bên trong trong của hàm trong. Điều nà cung cấp 1 loạt đống gói cho các biến của các chức năng bên trong.
  • Do các hàm bên trong không có quyền truy cập vào phạm vi của hafmg bên ngoài, các biến và hàm được định nghĩa trong hàm ngoài sẽ sống lâu hơn thời gian thực hiện hàm bên trong.
  • Closure được tạo khi chức năng bên trong nó được tạo, sẵn sàng cho bất kỳ các chức năng nào của hàm bên ngoài.

Ví dụ:

var pet = function(name) {   // The outer function defines a variable called "name"
  var getName = function() {
    return name;             // The inner function has access to the "name" variable of the outer 
                             //function
  }
  return getName;            // Return the inner function, thereby exposing it to outer scopes
}
myPet = pet('Vivie');
   
myPet();                     // Returns "Vivie"

Nó có thể phức tạp hơn nhiều so với đoạn code trên. Một đối tượng chứa các function để truy cập vào các biến bên trong của hàm ngoài (hàm có thể trả về)

var createPet = function(name) {
  var sex;
  
  return {
    setName: function(newName) {
      name = newName;
    },
    
    getName: function() {
      return name;
    },
    
    getSex: function() {
      return sex;
    },
    
    setSex: function(newSex) {
      if(typeof newSex === 'string' && (newSex.toLowerCase() === 'male' || 
        newSex.toLowerCase() === 'female')) {
        sex = newSex;
      }
    }
  }
}

var pet = createPet('Vivie');
pet.getName();                  // Vivie

pet.setName('Oliver');
pet.setSex('male');
pet.getSex();                   // male
pet.getName();                  // Oliver

Trong đoạn code trên thì biến name của function ngoài có thể truy cấp vào các function trong, và không có cách nào khác để truy cập vào các biến bên trong ngoại trừ thông qua các hàm bên trong. Các biến bên trong của các hàm bên trong hoạt động như các cửa hàng an toàn cho các đối số bên ngoài và các biến. Chúng giữ cho kiên cố(peristent) và đóng gói (encapsulated) dữ liệu cho các hàm bên trong làm việc. Các hàm này thậm chí không phải gán 1 biến, hoặc tên.

var getCode = (function() {
  var apiCode = '0]Eal(eh&2';    // A code we do not want outsiders to be able to modify...
  
  return function() {
    return apiCode;
  };
}());

getCode();    // Returns the apiCode

Tuy nhiên, có 1 số sai lầm cần lưu ý khi sử dụng closures

  • Nếu 1 hàm kết hợp định nghĩa 1 biến có cùng tên với tên của một biến trong phạm vi bên ngoài, thì không có cách nào để truy cập tới biến trong phạm vi bên ngoài nữa.
var createPet = function(name) {  // The outer function defines a variable called "name".
  return {
    setName: function(name) {    // The enclosed function also defines a variable called "name".
      name = name;               // How do we access the "name" defined by the outer function?
    }
  }
}

Trên đây là bài giới thiệu về Closures trong JavaScript của mình, mong nó sẽ giúp ích cho các bạn phần nào.

Thanks for watching!!!