2012-08-20 26 views
6

Muốn nhận nội dung nào đó ngay tại đây ... vì vậy tôi có 2 câu hỏiĐây có phải là những đóng cửa Javascript không?

Chức năng bên dưới tạo ra sự đóng.

function Foo(message){ 
    var msg = message; 

    return function Bar(){ 
     this.talk = function(){alert(msg); } 
    } 
}; 

Q: Những chức năng là việc đóng cửa, Foo hoặc Bar?
Tôi luôn nghĩ rằng việc đóng cửa là Foo, bởi vì nó đóng sau Bar khi trả lại Bar.

Tiếp ...

Dưới đây là định nghĩa của một chức năng ẩn danh:

()(); 

Q: Sản phẩm nội chức năng trong chức năng ẩn danh này cũng là một đóng cửa?

(function(){ /* <-- Is this function also a closure? */ })(); 
+0

Bạn không cần những thẻ '
' trong câu hỏi của mình. Ngoài ra, '()();' hoàn toàn không phải là định nghĩa của một hàm ẩn danh. – Pointy

+0

@Pointy Cảm ơn, tôi đã luôn luôn nói()(); là một hàm ẩn danh. Nếu không, nó được gọi là gì? –

+1

'()();' không có tên đặc biệt. Chữ '()' đầu tiên là toán tử nhóm để buộc nội dung được xem như là một biểu thức. Điều này được sử dụng để buộc định nghĩa hàm trở thành một biểu thức và không được coi là một câu lệnh. Hàm '()' thứ hai gọi hàm trong trường hợp này nhưng nó sẽ là một lỗi nếu kết quả của việc đánh giá toán tử nhóm không phải là một hàm. Một hàm ẩn danh chỉ đơn giản là một hàm không có tên. –

Trả lời

4

Bạn cần sử dụng nguyên tắc đầu tiên tại đây. Javascript sử dụng phạm vi từ vựng. Điều này có nghĩa là phạm vi của ngữ cảnh thực thi được xác định bằng cách mã được được định nghĩa (từ điển).

Tôi sẽ nói nét của hàm Bar là những gì gây việc đóng cửa được tạo ra, vì msg là "đóng trong" trong hàm.

Việc tạo ra thực tế của việc đóng cửa sẽ xảy ra trong thời gian chạy (trong đó có phần của một tuyên bố tautological, vì không có gì trong một chương trình máy tính sẽ xảy ra cho đến khi nó được điều hành), bởi vì để xác định giá trị của msg, trong Bar, khi Bar được thực hiện, thông dịch viên cần phải biết giá trị của biến khi Foo được thực hiện và do đó, hãy bật chuỗi.

Tôi sẽ đưa ra hai câu trả lời cho câu hỏi của bạn. Câu trả lời là: không phải chức năng nào cũng là đóng cửa. Đó là định nghĩa của các biến trong các hàm, được kết hợp với ngữ cảnh thực thi của các hàm khi chúng được chạy, nghĩa là định nghĩa đóng. Câu trả lời chung là: bất kỳ chức năng nào đóng trên một biến là một đóng (Thanh trong trường hợp của bạn).

Xem xét sự cố mọi người gặp phải khi sử dụng Javascript.

function A(x) { 
    var y = x, fs = []; 

    for (var i = 0; i < 3; i++) { 
     fs.push(function(){ 
     console.log (i + " " + x); 
     }) 
    } 

    fs.forEach(function(g){g()}) 
} 

A('hi') 

Hầu hết mọi người sẽ nói điều này sẽ tạo ra 'hi 1' theo sau là 'hi 2' theo sau là 'hi 3'. Tuy nhiên, nó tạo ra 'hi 3' 3 lần. Nếu chỉ định nghĩa của hàm được thêm vào mảng, trong khi sử dụng các biến được định nghĩa trong hàm bên ngoài, hãy tạo kết thúc, thì làm thế nào điều này có thể?

Đó là vì bạn cần ngữ cảnh thực hiện để xác định việc đóng cửa, điều này không xảy ra cho đến khi thời gian chạy. Khi thực hiện các hàm trong mảng, i có giá trị 3. Trong câu lệnh forEach, đó là ngữ cảnh thực thi, đó là lý do tại sao đầu ra luôn sử dụng 3.

+0

Ý bạn là "... khi Foo được giải thích." Tôi nghĩ. – Pointy

+1

Ý của bạn là gì? Sự tồn tại của 'Bar' và việc sử dụng' msg' là nguyên nhân gây ra sự đóng cửa. – hvgotcodes

1

Bar là đóng.

Chúng tôi nói rằng Barđóng trên biến số msg trong môi trường của nó.

Thông thường, từ đóng cửa có nghĩa là: một hàm sử dụng ít nhất một biến được xác định trong phạm vi bao quanh, trong hàm kèm theo.

Để trả lời câu hỏi thứ hai: (function(){ ... })() giống như một chức năng ẩn danh, không phải hai. Trừ khi nó được lồng vào bên trong một chức năng khác, bạn thường sẽ không gọi nó là một đóng cửa. Tuy nhiên, các hàm lồng nhau bên trong hàm ẩn danh đó có thể bị đóng (và thường là).

+0

+1 cho câu trả lời hoàn toàn ... Tôi ước tôi có thể bỏ phiếu cho hai câu trả lời. –

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