Tôi sẽ đưa ra một định nghĩa về sự đóng cửa, và nó sẽ chẳng có ý nghĩa gì cả. Và sau đó tôi sẽ tiếp tục với một vài ví dụ thực tế, và khi chúng ta đã trải qua một ví dụ thực tế, định nghĩa sẽ có ý nghĩa hoàn hảo
Định nghĩa đóng cửa
Một bao đóng là khi một hàm bên ngoài trả về một hàm bên trong, sau đó hàm bên trong được thực thi trong một phạm vi khác và hàm bên trong tiếp tục duy trì quyền truy cập vào các biến của hàm bên ngoài, mặc dù hàm bên ngoài không còn tồn tại
Xem video Youtube
Ví dụ đóng cửa 1. đóng cửa đơn giản
function greet[] {
const name = 'John';
return function [] {
console.log[`Hi ${name}`];
};
}
const greeting = greet[];
greeting[];
đầu ra
Hi John
Theo mệnh giá, bạn có thể nghĩ. "vấn đề lớn là gì?"
Chức năng bên ngoài trên dòng 1 đang trả về một chức năng bên trong trên dòng 4 và chức năng bên trong chỉ đơn giản là đăng xuất lời chào ra bàn điều khiển
Tuy nhiên, nếu bạn phân tích chức năng chi tiết hơn, bạn có thể nhận thấy một số hành vi kỳ lạ
Chẳng hạn, ở dòng 5, hàm bên trong đang tham chiếu đến tham số tên trong hàm bên ngoài
Bản thân điều này không hoàn toàn bất thường, bởi vì điều này chỉ đơn giản là sử dụng phạm vi từ vựng, nghĩa là một hàm có thể truy cập một biến được xác định bên ngoài hàm đó
Nhưng sau đó nếu bạn nhìn vào dòng 9, bạn sẽ thấy rằng tôi đã khai báo một biến có tên là hello, và biến này chứa hàm bên trong được trả về ở dòng 4. Nói cách khác, chức năng bên trong đã trở lại và chức năng bên ngoài không còn tồn tại
Hơn nữa, tại thời điểm hàm bên trong được gọi, nó tham chiếu đến tham số tên của hàm bên ngoài mặc dù hàm bên ngoài không còn tồn tại
Vậy làm thế nào để hàm bên trong có thể tham chiếu một tham số trong hàm bên ngoài nếu hàm bên ngoài không còn tồn tại?
Câu trả lời đơn giản là đóng cửa
Một bao đóng cho phép hàm bên trong được trả về quyền truy cập vào tất cả các biến trong hàm bên ngoài mà hàm bên trong tham chiếu, mặc dù hàm bên ngoài sẽ bị hủy vào thời điểm hàm bên trong được gọi
Chúng ta hãy xem lại định nghĩa về bao đóng, và lần này nó sẽ có ý nghĩa hơn một chút
Một bao đóng là khi một hàm bên ngoài trả về một hàm bên trong, sau đó hàm bên trong được thực thi trong một phạm vi khác và hàm bên trong tiếp tục duy trì quyền truy cập vào các biến của hàm bên ngoài, mặc dù hàm bên ngoài không còn tồn tại.
Kết thúc Ví dụ 2. Hàm đếm
function setCount[] {
let number = 0;
return function [] {
console.log[++number];
};
}
const counter = setCount[];
counter[];
counter[];
counter[];
Trong ví dụ này, tôi có một hàm setCount ở dòng 1 với một biến số ở dòng 2 được đặt thành 0
Trên dòng 4, một hàm bên trong ẩn danh được trả về để tăng biến số lên 1
Sau đó, ở dòng 9, một biến bộ đếm được khai báo chứa kết quả của lệnh gọi hàm setCount và kết quả của setCount là hàm bên trong được trả về ở dòng 4, do đó, một lần nữa, bộ đếm là một hàm chứ không phải một giá trị
Và cuối cùng, ở dòng 10, 11 và 12, hàm đếm được gọi 3 lần
Trước khi tôi chạy tập lệnh này, bạn nghĩ đầu ra sẽ là gì?
Hãy chạy tập lệnh và xem
đầu ra
1
2
3
Tại sao lại là kết quả 1, 2 và 3?
Bởi vì hàm bên trong tăng số ở dòng 4, nên bao đóng cho phép chúng ta truy cập vào biến số đã được khai báo mặc dù hàm bên ngoài đã bị hủy
Mỗi khi hàm đếm được gọi ở các dòng từ 10 đến 12, giá trị của biến số ở dòng 2 được tăng lên
Ví dụ này thể hiện rõ ràng khái niệm đóng cửa. Mặc dù chức năng bên ngoài không còn tồn tại, chức năng bên trong tiếp tục có quyền truy cập vào các biến của chức năng bên ngoài
Kết thúc Ví dụ 3. Đối với câu hỏi phỏng vấn vòng lặp
function addNumbers[] {
var numbers = [];
for [var i = 1; i