Bao đóng là sự kết hợp của một hàm và môi trường từ vựng mà trong đó hàm đó được khai báo.
function outerFunc() { var name = "TutorialsPoint"; // name is a local variable created by outerFunc return function innerFunc() { // innerFunc() is the inner function, a closure console.log(name); // use variable declared in the parent function }; } let f = outerFunc(); f()
externalFunc () tạo một biến cục bộ được gọi là tên và một hàm được gọi là innerFunc (). Hàm innerFunc () là một hàm bên trong được định nghĩa bên trong hàm externalFunc () và chỉ khả dụng trong phần thân của hàm ngoài ().
Lưu ý rằng hàm innerFunc () không có biến cục bộ của riêng nó. Tuy nhiên, vì các hàm bên trong có quyền truy cập vào các biến của các hàm bên ngoài, nên innerFunc () có thể truy cập vào tên biến được khai báo trong hàm mẹ, externalFunc ().
Bạn có thể thấy rằng tên đó đã vượt ra khỏi phạm vi khi bên ngoài hoàn thành việc thực thi. Nhưng nếu bạn nhìn kỹ, thì innerFunc được trả về và gán cho f vẫn có quyền truy cập vào biến tên. Do đó, bên trong func đã hình thành một sự đóng lại đối với phạm vi từ vựng của bên ngoài.
Công dụng thực tế
Mô phỏng các phương pháp riêng tư Các ngôn ngữ như Java cung cấp khả năng khai báo các phương thức là private, nghĩa là chúng chỉ có thể được gọi bởi các phương thức khác trong cùng một lớp. JavaScript không cung cấp cách thức nguyên bản để thực hiện việc này, nhưng có thể mô phỏng các phương thức riêng tư bằng cách sử dụng các bao đóng.
Ví dụ
var counter = (() => { var privateCounter = 0; let changeBy = (val) => privateCounter += val; return { increment: () => changeBy(1), decrement: () => changeBy(-1), value: () => privateCounter }; })(); console.log(counter.value()); counter.increment(); counter.increment(); console.log(counter.value()); counter.decrement(); console.log(counter.value());
Đầu ra
0 2 1
Sử dụng với trình xử lý sự kiện
for(let i = 0; i < 4; i++) { button = buttons[i] button.addEventListener("click", alert(i)) }
nếu bạn có 4 nút trong một nút bộ sưu tập và cố gắng thêm trình xử lý sự kiện như thế này, thì bất kỳ lần nhấp nào vào các nút đó sẽ dẫn đến kết quả là không xác định. Điều này là do khi họ được gọi, tôi sẽ không còn được xác định. Cách để giải quyết vấn đề này là giới thiệu một kết thúc so với i.
for(let i = 0; i < 4; i++) { button = buttons[i] button.addEventListener("click", () => alert(i)) }