2011-12-19 34 views
7

Tôi hiện đang thực hiện chuyển đổi để viết tất cả các mã javascript của tôi bằng cách sử dụng Coffeescript, Nhưng tôi thất vọng vì đơn giản nhất của các ví dụ là gây ra cho tôi vấn đề. Hiện tại, tôi đã thực hiện hơn một giờ nghiên cứu mà không thể tìm thấy câu trả lời cho điều này ...Tại sao cuộc gọi chức năng này không hoạt động khi sử dụng Coffeescript?

<!DOCTYPE html> 
<html> 
<head> 
    <script src="http://code.jquery.com/jquery-latest.js"></script> 
    <script src="http://jashkenas.github.com/coffee-script/extras/coffee-script.js" type="text/javascript" charset="utf-8"></script> 
    <link href="sheet.css" rel="stylesheet" type="text/css" media="screen" /> 
    <script type="text/coffeescript"> 
    $ -> 
     sayHi() 

    sayHi = -> 
     alert 'Hi there!' 
    </script> 
</head>  
<body> 
    <div id="all"> 
    </div> 
</body> 
</html> 

Vì nó rõ ràng từ đoạn mã trên, tôi chỉ đang cố gắng làm cho gọi hàm sayHi() hoạt động từ bên trong trình xử lý sẵn sàng của jQuery. Nhưng lỗi tôi nhận được như sau:

lỗi chưa gặp: không xác định không phải là một chức năng

Xin hãy giúp tôi, Theo trình biên dịch và hướng dẫn Tôi đã đọc tác phẩm này 'nên' , Nhưng tôi không biết những gì tôi đang làm sai lầm khủng khiếp cho điều này để không chạy: (

+0

ngoái, tôi đã kiểm tra, trình duyệt không có người phiên dịch CoffeeScript ... hoặc là "cà phê-sript.js" kịch bản dịch mã CoffeeScript vào JavaScript? –

+0

Bạn đã thử lật hai câu chưa? Tôi chưa bao giờ làm việc với CoffeeScript nhưng tôi cho rằng đó là do thực tế bạn đang gọi phương thức/chức năng trước khi nó được xác định (như quay lại C) –

+0

@ Šime Vidas Điều đó có nghĩa là những gì tôi đang làm là ....? – jlstr

Trả lời

11

text/coffeescript thẻ có sự khác biệt chính từ text/javascript thẻ. Họ không "chạy" cho đến khi tải tài liệu. thư viện tập lệnh phải tìm tất cả các thẻ tập lệnh cà phê và biên dịch chúng, và nó phải đợi cho đến khi DOM r eady vì vậy nó có thể chắc chắn để tìm thấy tất cả.

Vấn đề khác là jQuery sẽ kích hoạt cuộc gọi lại sẵn sàng DOM ngay lập tức nếu sự kiện đã xảy ra. Và trong trường hợp này nó có.

Vì vậy, khi điều này được biên soạn để JS bạn có được điều này:

var sayHi; 
$(function() { 
    return sayHi(); 
}); 
sayHi = function() { 
    return alert('Hi there!'); 
}; 

Vì vậy, những gì xảy ra là:

  • khai báo biến sayHi không có giá trị, làm cho nó undefined.
  • Tạo cuộc gọi lại DOM sẵn sàng cho jQuery sử dụng biến này.
  • jQuery chạy hàm gọi lại ngay lập tức vì DOM sẵn sàng đã xảy ra.
  • Chức năng gọi lại thực hiện và cố gắng chạy sayHi() vẫn chưa được xác định.
  • Sau khi chạy lại cuộc gọi, sayHi sau đó được đặt thành chức năng bạn muốn chạy.

Bây giờ nếu đây là một thẻ JS bình thường, nó có thể chạy trước khi tài liệu được tải, và sau đó nó đã hoạt động tốt vì thời gian gọi lại thực sự chạy, sau đó sayHi sẽ được gán đúng cách.

Để khắc phục, bạn nên gán chức năng TRƯỚC KHI bạn chạy qua trong gọi lại. Hoặc bạn có thể bỏ qua việc thực hiện hoàn toàn vì bạn biết DOM đã sẵn sàng bắn rồi. Nhưng thực sự, đây là một lý do chính khiến bạn không nên sử dụng các thẻ coffeescript. Nó thực sự không giống như sử dụng thẻ JS. Và một trong nhiều lý do đây không phải là cách tiếp cận được khuyến nghị để sử dụng CoffeeScript trên một trang web thực sự.

Vì vậy, biên dịch script cà phê của bạn trước khi trình duyệt của bạn thấy nó giống như một nhà phát triển có trách nhiệm :)

+0

Nhưng trình duyệt thực hiện tất cả các thành phần '

4

Lật lại những điều khoản. Có vẻ như CoffeeScript có cùng giới hạn như C cũ tốt, nơi bạn không thể thực hiện cuộc gọi đến hàm/phương thức cho đến khi nó được xác định theo thứ tự mã của bạn.

Vì vậy, sử dụng

thời gian
<script type="text/coffeescript"> 
    sayHi = -> 
    alert 'Hi there!' 

    $ -> 
    sayHi() 
</script> 
+0

Bạn có thể, sắp xếp. Nó sẽ có tác dụng, ngoại trừ trong trường hợp này gọi lại đang chạy ngay lập tức. Nếu nó chạy sau này nó sẽ làm việc tốt. –

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