Xem xét ví dụ sau:
function init() { var a = 3; // a là biến cục bộ của hàm init() function display () { // display() là một hàm khai báo trong init (inner function) alert(a); // dùng biến a của hàm init } display(); } init();
Bây giờ chúng sẽ viết lại ví dụ trên như sau:
function init() { var a = 3; // a là biến cục bộ của hàm init() function display () { // display() là một hàm khai báo trong init (inner function) alert(a); // dùng biến a của hàm init } return display; } Callfunc = init();// trả về hàm display Callfunc(); // thực thi hàm display
Kết quả đoạn mã trên vẫn là 3, nhưng có một vài khác biệt. Hàm display được trả về bởi hàm init trước khi thực thi. Chúng ta thấy rằng, hàm init đã hoàn tất thực thi khi trả về kết quả là lời gọi hàm display qua lệnh:
Callfunc = init();// trả về hàm display
Theo cách hiểu thông thường, lúc này các biến cục bộ của hàm init (như a) sẽ được giải phóng khi init thực thi xong, nhưng lệnh sau
Callfunc(); // thực thi hàm display
thực thi và hiển thị giá trị của biến a, là biến của hàm init. Để là được điều này, hàm Callfunc đã trở thành một closure.
* Vậy một closure là một hàm (Callfunc) có thể truy cập đến các biến (a) phạm vi của hàm cha (init) ngay cả khi hàm này đóng.
Xét ví dụ tiếp theo để hiểu hơn về closure:
function makeAdder(x) { return function(y) { return x + y; }; } var add5 = makeAdder(5); var add10 = makeAdder(10); alert(add5(2)); // 7 alert(add10(2)); // 12
hàm makeAdder có khai báo một biến x. Hàm này trả về một hàm nặc danh (không có tên hàm) có khai báo biến là y; hàm này trả về tổng x và y.
xét lệnh:
var add5 = makeAdder(5); // add5 là một closure
add5 là một closure và lệnh trên gán hàm nặc danh được trả về ởi makeAdder cho add5 và x = 5. Lệnh
alert(add5(2)); // 7
gán y = 2 và trả về tổng x và y, tức 7.
Ý kiến bài viết