2012-12-12 32 views
5

Mã sau đây được trình bày trong cuốn sách Head First jQuery.Biến không xác định, đôi khi

function lightning_one(t) { 
$("#lightning1").fadeIn(250).fadeOut(250); 
setTimeout("lightning_one()", t); 
}; // end lightning_one 

Nó được gọi với dòng này.

lightning_one(3000); 

Hành vi được quan sát là sét bị mất dần trong và ngoài một lần, chờ 3 giây, biến mất và tắt, sau đó tiếp tục mờ dần vào và ra. Firebug không hiển thị lỗi javascript.

Tôi hiểu tại sao tôi thấy những gì tôi thấy. Tôi nghĩ tôi sẽ cố gắng duy trì khoảng 3 giây, vì vậy tôi đã thay đổi này:

setTimeout("lightning_one()", t); // nothing in the brackets 

này:

setTimeout("lightning_one(t)", t); // t is in the brackets 

Khi tôi làm mới trang, sét mất dần trong và ngoài một lần. Firebug nói với tôi rằng biến t là không xác định.

Câu hỏi của tôi là, nếu biến t không được xác định sau khi thay đổi của tôi, lệnh chạy không có lỗi trước khi tôi thay đổi nó như thế nào? Nó vẫn có một biến có tên t.

More Info

Cảm ơn mọi người đã viết bình luận và câu trả lời. Đối với hồ sơ, trong thư mục "cuối", mã sẽ trở thành:

lightning_one(); 

    function lightning_one(){ 
$("#container #lightning1").fadeIn(250).fadeOut(250); 
setTimeout("lightning_one()",4000); 
    }; 

Tôi chưa hoàn thành chương áp dụng nên tôi không biết liệu thay đổi mã có được gợi ý sau này hay không. Như đã đề cập trước đó, đây có thể không phải là cuốn sách hay nhất ngoài kia. Tuy nhiên đó là một trong những tôi đã mua và tôi đang học các nguyên tắc cơ bản của jQuery từ nó.

+4

Họ thực sự chuyển một chuỗi tới 'setTimeout'? Ném cuốn sách đó ra xa. – Bergi

+0

Tôi đã suy nghĩ giống nhau: Tôi nghĩ cách gọi các chức năng theo cách này là một thực hành không tốt ... Không phải thứ gì đó nên được dạy trong một cuốn sách! – jahroy

+0

Tôi thấy nhiều từ ngữ có hiệu quả khi tôi cố tự tìm câu trả lời. Gọi hàm không có dấu ngoặc kép là một trong những nỗ lực không thành công của tôi. Vì mục đích của câu hỏi của tôi mặc dù, tôi nghĩ rằng một báo giá chính xác sẽ là cách tốt nhất để đi. –

Trả lời

6

Vì đối số đầu tiên của setTimeout dưới dạng chuỗi là eval -ed, có nghĩa là nó sẽ xem xét phạm vi bên ngoài của hàm mà trong đó t không được xác định. Việc đầu tiên là tốt bởi vì bạn không sử dụng bất kỳ biến nào trong cuộc gọi, nhưng thứ hai không phải là vì t không được định nghĩa bên ngoài phạm vi của hàm. Đó là trong thực tế địa phương.

Lời khuyên: Không sử dụng eval. Trong thực tế, bạn không cần đối số chuỗi. Sử dụng một biểu hiện chức năng:

setTimeout(function() { 

    lightning_one(t); 

}, t); 
2

này sẽ công việc:

setTimeout(function() { lightning_one(t); }, t); 

Tôi khá chắc chắn rằng cách gọi một hàm từ một String (và để cho nó được đánh giá) là một thói quen xấu mà nên tránh.

+0

Câu trả lời này thực sự hiệu quả. –

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