Hãy nói rằng bạn muốn có một chức năng mà bạn có thể sử dụng để trả về một "id" giá trị duy nhất để sử dụng khi bạn tạo các yếu tố DOM mới . Bây giờ, trong một cái gì đó như Java, bạn có thể tạo một lớp với một bộ đếm riêng bên trong, và sau đó có một phương thức nối thêm bộ đếm vào một chuỗi tiền tố. Vâng, trong Javascript:
var getId = (function() {
var counter = 0;
return function() {
return "prefix" + counter++;
};
})();
Bây giờ biến "getId" được ràng buộc với một chức năng đó là tạo bởi chức năng khác, và tạo ra theo cách như vậy mà nó có một biến dai dẳng để sử dụng giữa lời gọi. Tương tự như vậy, nếu tôi muốn có một gia đình của các chức năng "getId" (nói, một cho từng loại phần tử DOM tôi có thể thêm vào), tôi có thể làm điều này:
var getIdFunc = function(prefix) {
var counter = 0;
return function() {
return prefix + counter++;
};
};
var getId = {
'div': getIdFunc('div'),
'span': getIdFunc('span'),
'dl': getIdFunc('dl'),
// ...
};
Bây giờ tôi có thể gọi getId.div()
để có được một mới "id" giá trị cho một <div>
mới. Hàm được tạo bằng cách gọi một hàm cung cấp hai giá trị được lưu trữ trong một đóng: chuỗi tiền tố (được chuyển thành đối số) và bộ đếm (số var
được khai báo trong phạm vi đóng).
Một khi bạn quen với nó, cơ sở rất linh hoạt và hữu ích mà bạn sẽ cảm thấy đau khi di chuyển trở lại môi trường không có nó.
Oh, và đây là một mẹo để giúp giữ cho bạn khỏi StackOverflow bạn nên cố gắng này ra: đó là một vấn đề mà bật lên tất cả các thời gian:
for (var i = 0; i < 10; ++i) {
var id = "foo" + i;
var element = document.getElementById(id);
element.onclick = function() {
alert("hello from element " + i);
};
}
vấn đề ở đây là gì? Vâng, biến "i" được tham chiếu bởi hàm đó là "i" từ phạm vi mà vòng lặp đó chạy. Biến đó, bạn sẽ lưu ý, được tăng lên qua vòng lặp (duhh, phải không?). Vâng, mỗi một trong những chức năng nhỏ được tạo ra và được chỉ định là trình xử lý sự kiện sẽ chia sẻ cùng một biến duy nhất "i" trong phạm vi đóng. Rất tiếc! Giải pháp là làm điều gì đó như thế này:
for (var i = 0; i < 10; ++i) {
var id = "foo" + i;
var element = document.getElementById(id);
element.onclick = (function(iCopy) {
return function() {
alert("hello from element " + iCopy);
};
})(i);
}
Chúng tôi tạo một bản sao của "i" bên ngoài thành một phạm vi khép kín của riêng nó, vì vậy hiện nay mỗi người xử lý sự kiện đều có riêng!
Để tóm tắt: kỹ thuật tận dụng đóng cửa xuất hiện tất cả thời gian freaking khi bạn quen với nó. Nó không phải là một vé miễn phí vào một xứ sở mới của lập trình không có lỗi; đừng hiểu lầm tôi. Đó là, tuy nhiên, một mô hình rất hữu ích và linh hoạt.
ví dụ truy cập là cổ điển :). – Anshul