Bao đóng lập_trình máy_tính Trong khoa_học máy_tính bao đóng closure là một hàm hay một tham_chiếu tới một hàm cùng với môi_trường tham_chiếu một bảng chứa tham_chiếu đến mỗi biến không phải cục_bộ hay còn gọi là biến tự_do Closure còn được gọi với tên là lexical closure bao đóng hay function closure bao đóng hàm Bao đóng khác với một con_trỏ hàm thuần_tuý ở chỗ nó cho_phép một hàm có_thể truy_cập các biến không phải cục_bộ ngay cả khi hàm này được gọi ngoài phạm_vi của nó Ví_dụ Đoạn mã Python dưới đây định_nghĩa một hàm codice _ 1 với một biến cục_bộ codice _ 2 và một hàm lồng nested function codice _ 3 def counter Bao đóng được trả lại bởi codice _ 1 có_thể được gán cho một biến counter 1 _ increment counter counter 2 _ increment counter Khi chúng_ta gọi hàm codice _ 3 thông_qua bao đóng sẽ nhận được kết_quả như sau counter 1 _ increment 1 in ra kết_quả 1 counter 1 _ increment 7 in ra kết_quả 8 counter 2 _ increment 1 in ra kết_quả 1 counter 1 _ increment 1 in ra kết_quả 9 Sự khác_biệt về ngữ_cảnh Phạm_vi tác_dụng Các ngôn_ngữ_lập_trình khác nhau không phải lúc_nào cũng thống_nhất về lexical environment tạm dịch phạm_vi tác_dụng và định_nghĩa về bao đóng trong các ngôn_ngữ vì_thế cũng có_thể khác nhau Định_nghĩa đơn_giản nhất của lexical environment chỉ ra một tập các binding của các biến trong một phạm_vi nào đó Đó cũng chính là điều bao đóng muốn lưu_giữ capture lại Ý_nghĩa binding tạm dịch gắn_kết trong các ngôn_ngữ cũng khác nhau Trong các ngôn_ngữ mệnh_lệnh imperative languages các biến được gắn_kết đến các vùng bộ_nhớ lưu_trữ giá_trị của các biến đó Việc lưu_giữ lại các biến kiểu này được gọi là lưu_giữ bằng tham_chiếu capturing by reference Đoạn mã sau miêu_tả một ví_dụ trong ECMAScript_ECMAScript var f g function foo foo alert Gọi hàm g g hiện ra giá_trị 1 alert Gọi hàm f f hiện ra giá_trị 2 Trong ví_dụ trên hàm codice _ 6 và các bao đóng được tham_chiếu bởi các biến codice _ 7 và biến codice _ 8 đều sử_dụng chung một vùng bộ_nhớ khi truy_cập biến codice _ 2 Chính vì_vậy giá_trị của x đều thay_đổi sau mỗi lần gọi hàm codice _ 6 hay gọi các hàm qua các bao đóng codice _ 7 và biến codice _ 8 Trong khi đó rất nhiều các ngôn_ngữ_lập_trình khác ví_dụ như ngôn_ngữ ML việc gắn_kết biến lại đi liền trực_tiếp với giá_trị của biến Kiểu lưu_giữ này được gọi là lưu_giữ bằng giá_trị capturing by value Một_số ngôn_ngữ cho_phép chúng_ta lựa_chọn kiểu lưu_trữ theo ý_muốn Ví_dụ trong ngôn_ngữ C 11 hay PHP chúng_ta sử_dụng từ_khoá codice _ 13 để lưu_trữ biến theo tham_chiếu Khi không dùng từ_khoá đó các biến sẽ được lưu_trữ theo giá_trị Thoát khỏi phạm_vi tác_dụng Các ngôn_ngữ_lập_trình khác nhau cũng có sự khác nhau trong việc thoát khỏi phạm_vi tác_dụng xác_định bởi các lệnh của ngôn_ngữ đó ví_dụ codice _ 14 codice _ 15 hay codice _ 16 Ví_dụ sau chỉ ra sự khác_biệt trong hai ngôn_ngữ Smalltalk và ECMAScript_Smalltalk foo bar ECMAScript function foo alert foo in ra kết_quả 0 Các đoạn mã trên sẽ cho ra các kết_quả khác nhau vì toán_tử codice _ 17 của Smalltalk thực_thi khác với toán_tử codice _ 14 trong EMCAScript_Toán tử codice _ 14 trong EMCAScript sẽ thoát ra khỏi bao đóng phía trong và bắt_đầu một vòng lặp mới của vòng lặp codice _ 20 trong khi toán_tử codice _ 17 thực_thi trên biến codice _ 2 lệnh codice _ 23 sẽ kết_thúc vòng lặp codice _ 24 và trả lại chương_trình từ hàm codice _ 6
Bao đóng ( lập_trình máy_tính )