2010-07-20 38 views
13

Đang bao quanh đầu của tôi xung quanh đóng cửa JavaScript và tại một điểm mà mọi thứ đang rơi xuống tại chỗ; tức là việc đóng là các biến cục bộ cho một hàm - được giữ nguyên sau khi hàm đã trả về hoặc một đóng là một khung ngăn xếp không được phân phối khi hàm trả về.Tại sao chúng ta có bao đóng trong JavaScript?

Tôi bắt đầu hiểu khái niệm này, nhưng tôi càng hiểu tôi càng tự hỏi tại sao chúng ta phải sử dụng chúng.

Ví dụ như thế này làm cho tôi hiểu khái niệm nhưng để tôi hỏi, có một cách đơn giản hơn để làm điều này!

function sayHello(name) { 
    var text = 'Hello ' + name; 
    var sayAlert = function() { alert(text); } 
    sayAlert(); 
} 
sayHello('Gath'); 

Chỉ cần tự hỏi tại sao tôi phải giữ biến cục bộ còn sống? sau khi chức năng đã thoát?

Tôi có thể lấy ví dụ về các giải pháp được triển khai bằng cách đóng cửa ở đâu và không có gì khác có thể đã hoạt động nhưng đóng cửa?

+7

Nhìn vào đây để có một loạt câu trả lời tuyệt vời: http://stackoverflow.com/questions/111102/how-does-a-javascript-closure-work –

Trả lời

7

Đóng cửa thêm sức mạnh biểu cảm vào ngôn ngữ. Có một số mẫu có thể được triển khai rất dễ dàng do đóng cửa. Một vài ví dụ mà tôi suy nghĩ bao gồm:

0

Ví dụ bạn đã chọn xuất hiện trên this page, vì vậy tôi cho rằng bạn đã lấy nó từ đó. Bạn đã xem xét tất cả các ví dụ khác mà nó cung cấp chưa? Họ giải thích những động lực cho việc đóng cửa tốt hơn tôi có thể.

+0

Có, nhưng chúng vẫn không hiển thị một kịch bản mọi thứ khác thất bại và đóng cửa là điều duy nhất có thể thực hiện thủ thuật – gath

+0

@gath - đúng vậy. Nhiều ví dụ trong số đó là các hàm có các hàm khác làm giá trị trả lại của chúng. Nếu bạn gọi hàm bên ngoài, hãy lưu một tham chiếu đến hàm được trả về, và sau đó gọi hàm trả về tại một số điểm sau đó, các ví dụ đó không thể hoạt động mà không có các bao đóng. –

+0

@gath: Tất cả mọi thứ có thể được viết trong assembler. Đóng cửa không được phát minh để giải quyết các vấn đề mà không bao giờ có thể được giải quyết trước đây, vì vậy bạn sẽ không tìm thấy bất kỳ vấn đề mà chỉ có thể được giải quyết với đóng cửa. Họ làm cho một số vấn đề nhất định đơn giản hơn nhiều để giải quyết, và nếu bạn xem xét lại những ví dụ này với ý nghĩ này, chúng có thể bắt đầu có ý nghĩa hơn với bạn. –

2

Việc đóng là một hàm với tất cả các môi trường cần thiết để nó được thực thi. Trong javascript, đó là khi một hàm ẩn danh (= lambda) được tạo, sử dụng một biến từ một phạm vi bên ngoài.

Bạn có thể hiểu rõ hơn về lý do tại sao với một mã như thế:

function foo() 
{ 
    var text = computeFromOutside(); 
    // ... other lines of code 
    return function(otherText) { return text + otherText; } 
} 

bar = foo(); 

function baz(fun) 
{ 
    return fun("some text"); 
} 

Ở đây, bạn đang trở về một hàm sử dụng biến cục bộ "văn bản". Vì vậy, bạn đang rời khỏi phạm vi chức năng foo, phá hủy các biến của nó. Tuy nhiên, vì chúng ta có một hàm ẩn danh sử dụng văn bản, chúng ta phải theo dõi biến này. Điều này có thể đạt được bằng giá trị hoặc tham chiếu, tùy thuộc vào ngôn ngữ (Giữ biến còn sống (với khả năng sửa đổi sau đó, hoặc sao chép giá trị của nó khi hàm được tạo)).

Tôi hy vọng điều này sẽ hữu ích!

0

Một chức năng bình thường không nó điều, tính toán kết quả và trả về nó. Bằng cách trả lại một kết thúc, bạn có thể đóng gói công việc của bạn một phần thông qua, và cho phép người gọi nhận được nhiều hơn khi họ đã sẵn sàng cho nó. Vì tôi đã thử Scheme ở trường đại học, tôi đã khao khát đóng cửa bằng mọi ngôn ngữ tôi đã làm việc với từ đó ... họ đang hình thành thói quen nguy hiểm!

Chúng cũng được cho là một phần quan trọng của tương lai: cùng với các cơ chế lập trình chức năng khác có vẻ phù hợp để lập trình song song các hệ thống đa lõi.

2

"Đóng cửa là đối tượng của một người đàn ông nghèo. Một đối tượng là đóng cửa của người nghèo." (Xin lỗi, tôi quên nguồn).

Đôi khi, chúng tôi chỉ cần các biến cần thiết bởi một khối mã. Chúng tôi đặt khối mã đó vào một hàm và có các biến đó dưới dạng biến cục bộ cho hàm đó.

Đôi khi, chúng tôi cần các biến cần thiết bởi tất cả các chức năng/khối mã trong chương trình. Chúng ta có thể có các biến này dưới dạng biến toàn cục.

Đôi khi, chúng tôi cần các biến cần thiết bởi một số chức năng/khối mã. Ví dụ: chúng tôi có một thực thể được gọi là Bán hàng và chúng tôi muốn đặt tất cả các mã liên quan đến bán hàng của mình lại với nhau. Vì vậy, chúng tôi có một nhóm các chức năng và một nhóm các biến giao dịch với doanh số bán hàng. Chúng ta có thể đặt các hàm và các biến này lại với nhau trong một đối tượng, để chúng bị cô lập (cả các hàm và các biến) từ các phần mã khác.

Trong các ngôn ngữ không hỗ trợ trực tiếp các đối tượng, chúng tôi có thể có các hàm lồng nhau. Hàm bên ngoài hoạt động như lớp, các hàm bên trong hoạt động như các phương thức. Các biến cục bộ cho hàm bên ngoài hoạt động như các trường, chúng chỉ có thể truy cập được tới các hàm bên trong. Trong các cuộc gọi tiếp theo tới các hàm bên trong, chúng ta muốn duy trì trạng thái của các biến hàm cục bộ đến bên ngoài, đây là nơi cần đóng cửa. Tất cả những gì chúng ta phải làm là chuyển tham chiếu đến bất kỳ hàm bên trong nào thông qua đầu ra của hàm bên ngoài, để mã bên ngoài hàm bên ngoài, sao cho các biến của hàm ngoài được truy cập bởi hàm bên trong được bảo toàn ngay cả sau khi thoát hàm ngoài.

+0

đây là một sự tương tự tuyệt vời – qodeninja

Các vấn đề liên quan