Câu hỏi liên tưởng “Uncaught TypeError: object is not a function” trong Javascript


92

Mã như sau:

<body>
    <a href="javascript:;" id="test">hello</a>
</body>

<script type="text/javascript">
    document.getElementById("test").addEventListener("click", function () {
      test()
    }, false)
    function test() {
      var postTypes = new Array('hello', 'there')   
      (function() { alert('hello there') })()
    }
</script>

Điều này sẽ tạo ra:

"Uncaught TypeError: object không phải là một hàm"

Nếu tôi bọc lệnh gọi / lệnh gọi hàm ẩn danh trong một tập hợp dấu ngoặc đơn khác, nó sẽ thực thi cảnh báo, nhưng vẫn báo cho tôi lỗi. Nếu tôi đặt dấu chấm phẩy sau định nghĩa "var postTypes" thì nó sẽ hoàn toàn ổn.

Tôi tin rằng javascript không yêu cầu dấu chấm phẩy, vì vậy tôi đoán rằng có một số quy tắc kết hợp kỳ lạ của ứng dụng hàm mà tôi không hiểu đầy đủ. Tại sao tôi gặp lỗi này?


Có vẻ như bạn đang cố gắng tạo cả một hàm ẩn danh và hàm tĩnh và mong đợi nó thực thi như một. Điều gì xảy ra nếu bạn loại bỏ function ()
brumScouse

Câu trả lời:


85

JavaScript không yêu cầu dấu chấm phẩy, chỉ là trình thông dịch sẽ chèn chúng cho bạn khi ngắt dòng nếu có thể * .

Thật không may, mã

var a = new B(args)(stuff)()

không không gây ra một lỗi cú pháp, vì vậy không ;sẽ được chèn vào. (Một ví dụ có thể chạy là

var answer = new Function("x", "return x")(function(){return 42;})();

Để tránh những điều bất ngờ như thế này, hãy rèn luyện bản thân để luôn kết thúc câu nói bằng ;.


* Đây chỉ là một quy tắc ngón tay cái và không phải lúc nào cũng đúng. Quy tắc chèn phức tạp hơn nhiều. Đây trang blog về chèn dấu chấm phẩy có chi tiết hơn.


13
Hoặc: Để tránh những điều bất ngờ như thế này, hãy rèn luyện bản thân viết mã dễ đọc (nên luôn áp dụng) và biết các quy tắc chung của ASI ... nó thực sự không khác gì "biết" cách hoạt động của các bao đóng trong JS.

18

Mã của bạn gặp phải trường hợp quá trình Chèn dấu chấm phẩy tự động (ASI) không xảy ra.

Bạn không bao giờ nên dựa vào ASI. Bạn nên sử dụng dấu chấm phẩy để phân tách các câu lệnh một cách hợp lý:

var postTypes = new Array('hello', 'there'); // <--- Place a semicolon here!!

(function() { alert('hello there') })();

Mã của bạn thực sự đang cố gọi đối tượng mảng.


Một cách để khắc phục sự cố, nhưng tôi không thể vượt qua câu lạc bộ Crockford.

1
@pst: Hãy để tôi nói lại, tôi không tham gia câu lạc bộ Crock nào cả :)
Christian C. Salvadó 26/10/10

Trong trường hợp đó tôi xin lỗi vì những lời gay gắt :(

Tôi đã rất thích bài kiểm tra. ASI thực sự rất khó hiểu với mã icky!

8

Tôi gặp lỗi tương tự và tôi phải mất một lúc để nhận ra rằng trong trường hợp của mình, tôi đã đặt tên cho biến mảng là payInvoices và hàm cũng payInvoices. Nó khiến AngularJs bối rối. Sau khi tôi đổi tên thành processPayments (), nó cuối cùng đã hoạt động. Tôi chỉ muốn chia sẻ lỗi này và giải pháp vì tôi đã mất nhiều thời gian để tìm ra điều này.


Tương tự ở đây, tôi đã có một biến được đặt tên alertvà đang cố gắng gọi hàm cảnh báo javascript và nó sẽ thông báo 'alert không phải là một hàm'. Nó đang cố gắng gọi alertbiến thay vì hàm thực
James111 5/10/15

0

Cố gắng có phần thân hàm trước lệnh gọi hàm trong tệp JavaScript của bạn.


0

Tôi cũng gặp phải lỗi này và đã dành một ngày rưỡi để tìm giải pháp. Câu trả lời của Naomi dẫn tôi đến giải pháp tôi cần.

Đầu vào của tôi (loại = nút) có một thuộc tính namegiống với tên hàm đang được gọi bởi sự kiện onClick. Sau khi tôi thay đổi thuộc tính, namemọi thứ đều hoạt động.

<input type="button" name="clearEmployer" onClick="clearEmployer();">

thay đổi để:

<input type="button" name="clearEmployerBtn" onClick="clearEmployer();">

0

Tôi gặp lỗi này khi biên dịch và đóng gói TS với WebPack. Nó biên dịch export class AppRouterElement extends connect(store, LitElement){....}thành let Sr = class extends (Object(wr.connect) (fn, vr)) {....}có vẻ sai vì thiếu dấu phẩy. Khi kết hợp với Rollup, không có lỗi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.