2014-06-05 12 views
5

bước:Tại sao Firefox quên giá trị của biến? Giải pháp để gỡ lỗi?

  1. Mở trang trong Firefox 29.0.1 (Windows 7 x64):

    <!doctype html> 
    <title>Test</title> 
    <script> 
        (function() { 
         var x = 5, f = function() { 
          setTimeout(f, 1000); 
         }; 
         f(); 
        }()); 
    </script> 
    
  2. cụ mở cho nhà phát triển (F12).

  3. Trong Debugger, thiết lập một breakpoint trên: setTimeout(f, 1000);

  4. Một khi breakpoint là hit, đánh giá x trong giao diện điều khiển. Kết quả: undefined

    Screenshot showing when <code>x</code> is evaluated

  5. Nạp lại trang. Điểm ngắt được nhấn vào lần chạy đầu tiên của f.

  6. Đánh giá x. Kết quả: 5

  7. Tiếp tục thực hiện và khi điểm ngắt được nhấn lần nữa, hãy đánh giá x. Cùng một kết quả: 5

giả định của tôi: Nếu Firefox nhận ra trên đường chạy trốn đầu tiên của f rằng x là không cần thiết, sau đó nó không lưu trữ các giá trị của x "với" f. Vì vậy, trong các cuộc gọi tiếp theo đến f giá trị của xundefined. Thật thú vị, tôi thấy hành vi tương tự trong Chrome 35 và IE11.

Câu hỏi:Điều gì đang xảy ra? Tôi có thể định cấu hình Firefox để thực hiện x đánh giá đúng giá trị của nó trong bước 4 (xem ở trên) không?

+3

'x' chỉ tồn tại trong chức năng của bạn và bạn đang cố gắng truy cập nó từ ở ngoài. – Meredith

+0

Tôi không gặp phải vấn đề này. Khi tôi bước vào nó, nó đánh giá chính xác. Fox 23.0.1 được xây dựng trong các công cụ dev. Tôi đã trải nghiệm trình gỡ lỗi không hoạt động chính xác nếu bạn tải một trang, bắt đầu trình gỡ lỗi và cố gắng gỡ lỗi từ đó. Tôi đã từng phải tải trang, tải trình sửa lỗi, làm mới trang để làm cho nó hoạt động. –

+0

@Meredith Tôi đang truy cập 'x' từ điểm ngắt trên' setTimeout (f, 1000); ', là * bên trong * của hàm. – feklee

Trả lời

5

Dường như giả định của bạn là chính xác. Vấn đề là biến đã được tối ưu hóa hoặc gỡ bỏ khi trình gỡ lỗi không chạy. Khi bạn làm mới trang với trình gỡ rối đang chạy, nó sẽ cho phép bạn truy cập vào các phạm vi bên trong của các hàm để bạn có thể gỡ lỗi mã của mình dễ dàng hơn.

Điều này sẽ không thể thực hiện được nếu không có điểm ngắt ở đó, vì vậy trình biên dịch JIT phải được tắt để cho phép bạn làm như vậy. Bộ thu gom rác cũng lưu ý rằng chúng vẫn có thể được tham chiếu trong phạm vi, do đó, không loại bỏ các biến này.

Nếu trình biên dịch JIT đang chạy, nó sẽ nhận ra rằng biến số x không được sử dụng ở bất kỳ đâu và loại bỏ khỏi mã được tạo ra. Nếu trình biên dịch JIT là không hoạt động, thu gom rác (GC) sẽ loại bỏ biến khi chu kỳ GC chạy, vì không có gì đề cập đến biến.

Bởi vì nó không thể hoàn tác những gì nó đã làm, nó là không xác định khi bạn nhấn breakpoint lần đầu tiên.

Bạn thực sự không thể ngăn điều này xảy ra, ngay cả khi bạn tắt trình biên dịch JIT.Mặc dù về mặt kỹ thuật, bạn có thể đặt giới hạn bộ sưu tập rác thực sự cao để cố gắng dừng nó làm như vậy hoặc thậm chí loại bỏ mã thu gom rác và xây dựng lại Firefox, điều đó khá ngu ngốc - bạn sẽ chỉ bị rò rỉ một bộ nhớ và rắc rối hơn là làm mới trang.

Điều thú vị là mặc dù, Firefox 31 (Aurora) cung cấp một thông báo lỗi mô tả nhiều hơn nếu bạn cố gắng và làm điều tương tự:

Error: variable has been optimized out 
+0

Cảm ơn, đặc biệt đối với kết quả tìm kiếm mà Aurora đưa ra một thông báo lỗi mô tả hơn! Tôi vừa xác nhận rằng trên hệ thống của tôi. BTW bạn có thể loại bỏ dòng đầu tiên của câu trả lời của bạn: Tôi bây giờ cũng nhận được 'undefined'. Có thể có một vấn đề khác, hoặc có thể tôi đã ở sai tab khi tôi sao chép thông báo lỗi. – feklee

+0

Thật tuyệt khi biết chi tiết về hành vi này, nó cảnh báo chính xác trong Firefox, nhưng tôi tự hỏi nếu các lỗi nghiêm trọng hơn như https://bugzilla.mozilla.org/show_bug.cgi?id=977972, https: // bugzilla .mozilla.org/show_bug.cgi? id = 582613 đã được sửa trong phiên bản này? Thành thật mà nói, tôi thường phải thử Chrome/Chromium cho trình gỡ rối JS của nó, mặc dù mọi thứ khác đều tốt hơn trong Firefox. – NoBugs

+0

@NoBugs: xin lỗi, không chắc chắn về điều đó - Tôi không thực sự sử dụng Aurora nhiều như vậy. –

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