Bao đóng (lập trình máy tính)

Ví dụ

Đoạn mã Python dưới đây định nghĩa một hàm counter với một biến cục bộ x và một hàm lồng (nested function) increment
def counter():
    x = 0
    def increment(y):
        nonlocal x
        x += y
        print(x)
    return increment
Bao đóng được trả lại bởi counter có thể được gán cho một biến:
counter1_increment = counter()counter2_increment = counter()
Khi chúng ta gọi hàm increment thông qua bao đóng sẽ nhận được kết quả như sau:
counter1_increment(1)    # in ra kết quả 1counter1_increment(7)    # in ra kết quả 8counter2_increment(1)    # in ra kết quả 1counter1_increment(1)    # in ra kết quả 9

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
// ECMAScriptvar f, g;function foo() {
  var x = 0;
  f = function() { return ++x; };
  g = function() { return --x; };
  x = 1;
  alert('Bên trong foo, gọi hàm f(): ' + f()); // hiện ra giá trị "2"}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 foo và các bao đóng được tham chiếu bởi các biến f và biến g đều sử dụng chung một vùng bộ nhớ khi truy cập biến x. Chính vì vậy giá trị của x đều thay đổi sau mỗi lần gọi hàm foo hay gọi các hàm qua các bao đóng f và biến g
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ừ khóa & để lưu trữ biến theo tham chiếu. Khi không dùng từ khóa đó, 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ụ: return, break hay continue.
Ví dụ sau chỉ ra sự khác biệt trong hai ngôn ngữ Smalltalk và ECMAScript:
"Smalltalk"foo
  | xs |
  xs:= #(1 2 3 4).
  xs do: [:x | ^x].
  ^0bar
  Transcript show: (self foo printString) "in ra kết quả 1"
// ECMAScriptfunction foo() {
  var xs = [1, 2, 3, 4];
  xs.forEach(function (x) { return x; });
  return 0;}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ử ^ của Smalltalk thực thi khác với toán tử return trong EMCAScript. Toán tử return 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 forEach trong khi toán tử ^ thực thi trên biến x (lệnh ^x sẽ kết thúc vòng lặp do và trả lại chương trình từ hàm foo.