2010-04-28 48 views
10

Kiểm tra các đoạn mã sau đây HTML/Javascript:Phạm vi của biến Javascript được khai báo trong vòng lặp for() là gì?

<html> 
<head> 
<script type="text/javascript"> 
var alerts = []; 
for(var i = 0; i < 3; i++) { 
    alerts.push(function() { document.write(i + ', '); }); 
} 

for (var j = 0; j < 3; j++) { 
    (alerts[j])(); 
} 

for (var i = 0; i < 3; i++) { 
    (alerts[i])(); 
} 
</script> 
</head><body></body></html> 

đầu ra này:

3, 3, 3, 0, 1, 2 

mà không phải là những gì tôi đã mong đợi - Tôi đã chờ đợi đầu ra 0, 1, 2, 0, 1, 2,

tôi (không chính xác) giả định rằng hàm ẩn danh được đẩy vào mảng sẽ hoạt động như một đóng, bắt giá trị i được gán khi hàm được tạo - nhưng nó thực sự xuất hiện là i hoạt động như một biến toàn cục.

Bất cứ ai có thể giải thích điều gì đang xảy ra với phạm vi i trong ví dụ mã này hay không và tại sao hàm ẩn danh không ghi lại giá trị của nó?

Trả lời

6

Trong Javasript, ranh giới phạm vi từ vựng "thú vị" duy nhất là nội dung hàm. Bất cứ điều gì được khai báo ở bất cứ nơi nào trong một hàm (tốt, bất cứ nơi nào khác với một hàm lồng nhau khác) đều nằm trong cùng một phạm vi. Ngoài ra còn có một số điều kỳ lạ về cách mà các tờ khai được giải thích.

Chức năng ẩn danh của bạn hoạt động như một đóng, nhưng mỗi hàm được khởi tạo sẽ chia sẻ cùng một "i". Một thủ thuật tôi sử dụng là thêm một lớp chức năng:

for (var i = 0; i < whatever; i++) { 
    (function(idaho) { 
    whatever(function() { alert("my own private " + idaho); }); 
    })(i); 
} 

Tại somepoint hy vọng tất cả các trình duyệt sẽ hỗ trợ mới "chúng ta hãy" tuyên bố, mà là một cách ngắn hơn, ít lạ-tìm cách để làm cơ bản điều tương tự .

8

Phạm vi là hàm mà biến được xác định trong (ngoại trừ không có biến, vì vậy nó là toàn cầu).

Chức năng ẩn danh bạn đang truyền đang truy cập biến được xác định trong phạm vi của hàm cha (toàn cục).

Bạn cần đóng cửa thực tế.

alerts.push(
    function (foo) { 
     return function() { 
      document.write(foo + ', '); 

     } 
    }(i) 
); 
+0

Câu trả lời đúng - cảm ơn! - nhưng tôi đã chấp nhận câu trả lời của Pointy vì "riêng tư của tôi" + idaho khiến tôi cười lớn ... –

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