未捕获的TypeError :(中间值)(...)不是函数

arm*_*ong 91 javascript typeerror

当我在一个闭包中将js逻辑写为单个js文件时,一切正常,如下:

(function(win){
   //main logic here
   win.expose1 = ....
   win.expose2 = ....
})(window)
Run Code Online (Sandbox Code Playgroud)

但是当我尝试在同一个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)
Run Code Online (Sandbox Code Playgroud)

它抱怨有一个TypeError:

Uncaught TypeError: (intermediate value)(...) is not a function
Run Code Online (Sandbox Code Playgroud)

我做错了什么?

Jos*_*ier 218

该错误是第三行缺少分号的结果:

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

(function(win) {
  // ...
})(window);
Run Code Online (Sandbox Code Playgroud)

ECMAScript规范具有自动分号插入的特定规则,但是在这种情况下,分号不会自动插入,因为从下一行开始的括号表达式可以解释为函数调用的参数列表.

这意味着如果没有该分号,则window.Glog使用函数作为msg参数调用匿名函数,然后(window)随后尝试调用返回的任何内容.

这就是代码的解释方式:

window.Glog = function(msg) {
  console.log(msg);
}(function(win) {
  // ...
})(window);
Run Code Online (Sandbox Code Playgroud)

  • @armnotstrong Josh更快,答案是一样的:) (4认同)
  • 惊人的!!!非常感谢!!我差点把这头发都掉光了…… (3认同)
  • 这太疯狂了,我非常感谢这篇文章。当我不断收到“...不是函数”错误时,我正在 React `useEffect()` 函数中的 `if` 语句之后设置状态。 (3认同)
  • 谢谢你,先生!我的 linter 自动删除了分号,一切都坏了:) (2认同)

Nic*_*one 14

使分号规则变得简单

(, [, ` 或任何运算符(/、+、- 是唯一有效的)开头的每一行都必须以分号开头才能被解释为它自己的行。所有其他换行符都是隐式的。

就是这样。完毕。


为什么?

考虑以下:

func()
;[0].concat(myarr).forEach(func)
;(myarr).forEach(func)
;`hello`.forEach(func)
;/hello/.exec(str)
;+0
;-0
Run Code Online (Sandbox Code Playgroud)

遵循上述规则可防止上述内容被解释为

func()[0].concat(myarr).forEach(func)(myarr).forEach(func)`hello`.forEach(func)/hello/.forEach(func)+0-0
Run Code Online (Sandbox Code Playgroud)

补充说明

提到会发生什么:括号将索引,括号将被视为函数参数。反引号将转换为带标签的模板,正则表达式将转换为除法,而明确的 +/- 有符号整数将转换为加/减运算符。

当然,您可以通过在每个换行符的末尾添加一个分号来避免这种情况,但即使这样做也不总是对您有帮助,因为当您以分号结束一行时,它可能会在您的代表。所以请记住以下语句

return       // Implicit semicolon, will return undefined.
    (1+2);

i        // Implicit semicolon on this line
   ++;   // But, if you intended "i++;" and you wrote it like this,
         // you need help.
Run Code Online (Sandbox Code Playgroud)

上述情况会发生在返回/继续/中断/++/--。任何 linter 都会用死代码或 ++/-- 语法错误(++/-- 永远不会发生)来捕获它。

最后,如果您希望文件串联工作,请确保每个文件都以分号结尾。如果您使用的是打包程序(推荐),它应该会自动执行此操作。


tfr*_*oli 7

对我来说,这要简​​单得多,但我花了一段时间才弄清楚。我们基本上在 .jslib 中有

some_array.forEach(item => {
    do_stuff(item);
});
Run Code Online (Sandbox Code Playgroud)

事实证明 Unity(emscripten?)就是不喜欢这种语法。我们用一个好的旧 for 循环替换了它,它立即停止了抱怨。我真的很讨厌它没有显示出它所抱怨的线条,但无论如何,愚弄我两次对我来说是耻辱。


小智 7

当我创建根类时,我使用箭头函数定义了其方法。在继承和覆盖原始函数时,我注意到同样的问题。

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

let add = new CC;
console.log(add.x(4));
Run Code Online (Sandbox Code Playgroud)

这是通过定义没有箭头函数的父类的方法来解决的

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

let add = new CC;
console.log(add.x(4));
Run Code Online (Sandbox Code Playgroud)


Sha*_*pta 6

  **Error Case:**

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

(function() {     //IIFE
 // some code
})();
Run Code Online (Sandbox Code Playgroud)

输出:类型错误:(中间值)(中间值)不是函数*如何修复它->因为您缺少半colan(;)来分隔表达式;

 **Fixed**


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

(function() {     //IIFE
 // some code
})();
Run Code Online (Sandbox Code Playgroud)

为什么会出现这个错误?原因: ES6 标准中给出的自动分号插入的特定规则


Sha*_*pta 5

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

( cameraInfo.findtext != "" ) ? searchQuery : userListQuery;
Run Code Online (Sandbox Code Playgroud)

输出:TypeError :(中间值)(中间值)不是函数

*如何修复IT - > 因为您缺少半可乐(;)来分隔表达式;

TypeError: (intermediate value)(intermediate value) is not a function
Run Code Online (Sandbox Code Playgroud)


Ame*_*icA 5

我在这种情况下遇到了同样的问题:

let brand, capacity, color;
let car = {
  brand: 'benz',
  capacity: 80,
  color: 'yellow',
}

({ color, capacity, brand } = car);
Run Code Online (Sandbox Code Playgroud)

只需;在声明末尾加上一个car,错误就消失了:

let car = {
  brand: 'benz',
  capacity: 80,
  color: 'yellow',
}; // <-------------- here a semicolon is needed
Run Code Online (Sandbox Code Playgroud)

其实,之前({ color, capacity, brand } = car);是需要看到分号的。