2010-08-04 44 views
5

Tôi có một số Javascript hoạt động để điều khiển một số phần tử DOM. Vấn đề là, tôi không hiểu lý do tại sao nó hoạt động, đó không bao giờ là một điều tốt. Tôi đang cố gắng tìm hiểu thêm về các phương pháp hay nhất về javascript và javascript hướng đối tượng, vì vậy tổ chức có thể có vẻ hơi lạ.

Về cơ bản, tôi bọc hai phương thức thao tác DOM bên trong đối tượng CSContent. Tôi tạo một thể hiện của đối tượng đó, content trong $(document).ready và liên kết một số sự kiện với các chức năng trong content. Tuy nhiên, tôi đang bối rối như thế nào các chức năng này vẫn có thể được gọi sau khi thoát $(document).ready. Điều đó có nghĩa là content đã hết phạm vi và chức năng của nó không khả dụng? Dù sao, đây là mã:

+0

Bạn có thể hiển thị ví dụ về nơi bạn có quyền truy cập vào 'nội dung' mà bạn không nên có? –

+0

@Pekka: khi trong phần tử có id 'edit-cscontent-cs-content-tweet', một phím được nhấn hoặc bị nén, chẳng hạn? –

+0

@Marcel ahh, đó là ý của anh ấy! Đó là một đóng cửa. Nhưng bạn đã giải thích rằng trong câu trả lời của bạn - sẽ +1 nhưng tôi đã bỏ phiếu cho ngày hôm nay. –

Trả lời

2

Tôi giả sử bạn tự hỏi tại sao các trình xử lý sự kiện như

$('#edit-cscontent-cs-content-twitter').change(content.toggleTweetTextarea); 

làm việc?

Bạn không vượt qua content làm trình xử lý sự kiện nhưng chức năng được chứa trong content.toggleTweetTextarea. Và tham chiếu này sẽ vẫn tồn tại sau content không tồn tại nữa. Không có gì đặc biệt về nó. Bạn chỉ cần gán một đối tượng (hàm) cho một biến khác. Miễn là ít nhất một tham chiếu đến một đối tượng tồn tại, đối tượng sẽ không được thu thập rác.

Bây giờ bạn có thể hỏi tại sao những chức năng đó vẫn có quyền truy cập vào ví dụ: tweetTextArea? Điều này thực sự là một đóng cửa. Khi các hàm được tạo thông qua new CSContent(), ngữ cảnh kích hoạt của hàm này được thêm vào chuỗi phạm vi của các hàm bên trong CSContent.toggleTweetTextareaCSContent.updateTweetCharacterCount. Vì vậy, ngay cả khi bạn không có tham chiếu đến content nữa, phạm vi của hàm này vẫn được chứa trong chuỗi phạm vi của các hàm khác.

Bạn sẽ không thể truy cập đối tượng chứa trong content nữa sau khi ready() hoàn tất, điều này thực sự nằm ngoài phạm vi.

5

này, m'lord, được gọi là đóng cửa: các biến cục bộ content sẽ vẫn trong bộ nhớ sau khi $(document).ready thoát. Đây cũng là nguyên nhân gây ra rò rỉ bộ nhớ.

Tóm lại, bạn liên kết hàm này với trình xử lý sự kiện của phần tử DOM và sau đó trình thu thập rác JavaScript biết rằng nó sẽ giữ nguyên biến cục bộ. Bạn không thể gọi nó trực tiếp (bên ngoài chức năng), trừ khi sự kiện được kích hoạt. Với một số, bạn có thể thực hiện việc này theo cách thủ công, nếu sau đó bạn thực sự muốn gọi hàm này (ví dụ: sử dụng element.click() để mô phỏng nhấp chuột).

+0

Nhưng khác hơn thế, chúng thật tuyệt vời! :) Một số đọc bổ sung: https: //developer.mozilla.org/vi/JavaScript/Hướng dẫn/Đóng cửa –

+0

Vì vậy, nó có thể truy cập vào các biến cục bộ được khai báo trong hàm dựng CSContent vì nó là một đóng và nó không nằm ngoài phạm vi vì nó bị ràng buộc với một trình lắng nghe sự kiện? Hay toàn bộ việc đóng cửa có được sao chép bằng cách nào đó đến người nghe sự kiện không? – jergason

+0

@Jergason: thứ nhất. –

1

Bộ não của tôi tắt hôm nay, nhưng bạn có nên sử dụng các bao đóng trong trường hợp này không?

$('#edit-cscontent-cs-content-twitter').change( 
    function(){ 
     content.toggleTweetTextarea(); 
    } 
); 
+0

Hôm nay ....? :) Hey Eric bạn đã bao giờ thấy nhận xét này chưa: http://stackoverflow.com/questions/3274044/best-book-on-ajax/3306936#3306936 –

+0

Hmm, ý tưởng hay, đóng cửa. Nhưng OP đã sử dụng một…: P –

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