Uncaught TypeError: (giá trị trung gian) (…) không phải là một hàm


128

Mọi thứ hoạt động tốt khi tôi viết logic js trong một bao đóng dưới dạng một tệp js duy nhất, như:

(function(win){
   //main logic here
   win.expose1 = ....
   win.expose2 = ....
})(window)

nhưng khi tôi cố gắng chèn một hàm thay thế ghi nhật ký trước khi đóng đó trong cùng một tệp js,

 window.Glog = function(msg){
     console.log(msg)
 }
 // this was added before the main closure.

 (function(win){
   //the former closure that contains the main javascript logic;
 })(window)

nó phàn nàn rằng có TypeError:

Uncaught TypeError: (intermediate value)(...) is not a function

Tôi đã làm gì sai?

Câu trả lời:


275

Lỗi là do thiếu dấu chấm phẩy trên dòng thứ ba:

window.Glog = function(msg) {
  console.log(msg);
}; // <--- Add this semicolon

(function(win) {
  // ...
})(window);

Đặc tả ECMAScript có các quy tắc cụ thể để tự động chèn dấu chấm phẩy , tuy nhiên trong trường hợp này, dấu chấm phẩy không được tự động chèn vì biểu thức dấu ngoặc đơn bắt đầu ở dòng tiếp theo có thể được hiểu là danh sách đối số cho một lệnh gọi hàm.

Điều này có nghĩa là nếu không có dấu chấm phẩy đó, thì window.Gloghàm ẩn danh đang được gọi với một hàm làm msgtham số, theo sau (window)đó là hàm sau đó cố gắng gọi bất cứ thứ gì được trả về.

Đây là cách mã được diễn giải:

window.Glog = function(msg) {
  console.log(msg);
}(function(win) {
  // ...
})(window);

4
@armnotstrong Josh nhanh hơn và câu trả lời cũng giống nhau :)
mrlew

1
Cảm ơn ngài! Linter tôi loại bỏ các dấu chấm phẩy automagically và tất cả mọi thứ đã phá vỡ :)
Jonas Lomholdt

1
tuyệt vời!!! Cảm ơn bạn rất nhiều!! Tôi gần như mất hết tóc của tôi trên một này ...
TMS

1
Đây, bạn của tôi, là vàng!
LihO

1
điều này thật điên rồ và tôi rất biết ơn về bài đăng này. Tôi đang đặt trạng thái sau một ifcâu lệnh trong useEffect()hàm React khi tôi liên tục nhận được lỗi "... không phải là một hàm".
Rahul Nath

7

Để đơn giản hóa các quy tắc về dấu chấm phẩy

Mọi dòng bắt đầu bằng dấu (, [`hoặc bất kỳ toán tử nào (/, +, - là những toán tử hợp lệ duy nhất), phải bắt đầu bằng dấu chấm phẩy.

func()
;[0].concat(myarr).forEach(func)
;(myarr).forEach(func)
;`hello`.forEach(func)
;/hello/.exec(str)
;+0
;-0

Điều này ngăn cản một

func()[0].concat(myarr).forEach(func)(myarr).forEach(func)`hello`.forEach(func)/hello/.forEach(func)+0-0

quái dị.

Ghi chú bổ sung

Để đề cập đến những gì sẽ xảy ra: dấu ngoặc sẽ lập chỉ mục, dấu ngoặc sẽ được coi là tham số của hàm. Backtick sẽ biến đổi thành một mẫu được gắn thẻ và regex hoặc các số nguyên có dấu rõ ràng sẽ chuyển thành các toán tử. Tất nhiên, bạn chỉ có thể thêm dấu chấm phẩy vào cuối mỗi dòng. Tuy nhiên, thật tốt khi bạn đang tạo mẫu nhanh chóng và bỏ dấu chấm phẩy.

Ngoài ra, việc thêm dấu chấm phẩy vào cuối mỗi dòng sẽ không giúp bạn thực hiện những điều sau đây, vì vậy hãy ghi nhớ những câu như

return // Will automatically insert semicolon, and return undefined.
    (1+2);
i // Adds a semicolon
   ++ // But, if you really intended i++ here, your codebase needs help.

Trường hợp trên sẽ xảy ra để trả về / tiếp tục / break / ++ / -. Bất kỳ linter nào cũng sẽ mắc lỗi này với mã chết hoặc lỗi cú pháp ++ / - (++ / - sẽ không bao giờ xảy ra trên thực tế).

Cuối cùng, nếu bạn muốn nối tệp hoạt động, hãy đảm bảo mỗi tệp kết thúc bằng dấu chấm phẩy. Nếu bạn đang sử dụng chương trình gói (được khuyến nghị), chương trình sẽ tự động thực hiện việc này.


5

Trường hợp lỗi:

var userListQuery = {
    userId: {
        $in: result
    },
    "isCameraAdded": true
}

( cameraInfo.findtext != "" ) ? searchQuery : userListQuery;

Đầu ra:

TypeError: (intermediate value)(intermediate value) is not a function

Khắc phục: Bạn đang thiếu dấu chấm phẩy (;) để phân tách các biểu thức

userListQuery = {
    userId: {
        $in: result
    },
    "isCameraAdded": true
}; // Without a semi colon, the error is produced

( cameraInfo.findtext != "" ) ? searchQuery : userListQuery;

3

Đối với tôi, nó đơn giản hơn nhiều nhưng tôi phải mất một thời gian để tìm ra nó. Về cơ bản, chúng tôi đã có trong .jslib của mình

some_array.forEach(item => {
    do_stuff(item);
});

Hóa ra Unity (emscripten?) Không thích cú pháp đó. Chúng tôi đã thay thế nó bằng một vòng lặp cũ tốt và nó ngừng phàn nàn ngay lập tức. Tôi thực sự ghét nó rằng nó không hiển thị dòng mà nó đang phàn nàn, nhưng dù sao, lừa tôi hai lần xấu hổ về tôi.


tôi đoán là vấn đề của bạn là một cái gì đó để làm với này
Brandito

Đây là một trường hợp khác với những gì câu hỏi là về.
CherryDT

@CherryDT thì không, vì lỗi tôi nhận được là chính xác.
tfrascaroli

Không, câu hỏi này là về các lỗi bạn gặp phải khi vô tình gọi một cái gì đó dưới dạng một hàm do không có dấu chấm phẩy tồn tại giữa câu lệnh và một (trên dòng tiếp theo. Tôi không thấy điều đó trong trường hợp của bạn. Câu hỏi không chỉ bao gồm tiêu đề của nó!
CherryDT

1

Tôi đã gặp phải vấn đề này khi tôi tạo một lớp ES2015 mới trong đó tên thuộc tính bằng tên phương thức.

ví dụ:

class Test{
  constructor () {
    this.test = 'test'
  }

  test (test) {
    this.test = test
  }
}

let t = new Test()
t.test('new Test')

Xin lưu ý rằng việc triển khai này là trong NodeJS 6.10.

Để giải quyết vấn đề này (nếu bạn không muốn sử dụng tên phương thức 'setTest' nhàm chán), bạn có thể sử dụng tiền tố cho các thuộc tính 'riêng tư' của mình (như _test).

Mở Công cụ dành cho nhà phát triển của bạn trong jsfiddle .


Đây là một trường hợp khác với những gì câu hỏi là về.
CherryDT

0
  **Error Case:**

var handler = function(parameters) {
  console.log(parameters);
}

(function() {     //IIFE
 // some code
})();

Output: TypeError: (middle value) (giá trị trung gian) không phải là hàm * Cách sửa lỗi IT -> do bạn thiếu dấu chấm phẩy (;) để phân cách các biểu thức;

 **Fixed**


var handler = function(parameters) {
  console.log(parameters);
}; // <--- Add this semicolon(if you miss that semi colan .. 
   //error will occurs )

(function() {     //IIFE
 // some code
})();

tại sao lỗi này đến ?? Lý do: các quy tắc cụ thể cho tính năng chèn dấu chấm phẩy tự động được cung cấp cho các cột sao ES6


0

Khi tôi tạo một lớp gốc, có các phương thức mà tôi đã xác định bằng các hàm mũi tên. Khi kế thừa và ghi đè chức năng ban đầu, tôi nhận thấy cùng một vấn đề.

class C {
  x = () => 1; 
 };
 
class CC extends C {
  x = (foo) =>  super.x() + foo;
};

let add = new CC;
console.log(add.x(4));

điều này được giải quyết bằng cách xác định phương thức của lớp cha không có hàm mũi tên

class C {
  x() { 
    return 1; 
  }; 
 };
 
class CC extends C {
  x = foo =>  super.x() + foo;
};

let add = new CC;
console.log(add.x(4));
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.