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


128

当我将闭包中的js逻辑作为单个js文件编写时,一切工作正常,例如:

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

但是,当我尝试在同一个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)

它抱怨有一个TypeError:

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

我做错什么了?

Answers:


275

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

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

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

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

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

这是解释代码的方式:

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

4
@armnotstrong Josh更快,答案也一样:)
mrlew

1
谢谢你,先生!我的棉绒

1
太棒了!!! 非常感谢!!我几乎把所有头发都弄丢了
TMS

1
我的朋友,这是金子!
LihO '18 -10-30

1
这太疯狂了,我非常感谢这篇文章。当我不断收到此“ ...不是函数”错误时,我if正在React useEffect()函数中的语句后设置状态。
拉胡尔·纳特

7

使分号规则变得简单

与一开始每一行([`,或任何运算符(/,+, -是唯一有效的),必须用分号开始。

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

这样可以防止

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

怪物。

附加说明

提到会发生什么:括号将索引,括号将被视为函数参数。反引号将转换为带标签的模板,而regex或显式签名的整数将转换为运算符。当然,您可以在每行末尾添加一个分号。不过,当您快速进行原型制作并放弃分号时,请紧记一下。

另外,在每行的末尾添加分号不会对您有所帮助,因此请记住以下语句

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.

以上情况将发生在return / continue / break / ++ /-。任何短毛猫都会遇到死代码或++ /-语法错误(++ /-绝对不会发生)。

最后,如果您希望文件串联起作用,请确保每个文件都以分号结尾。如果您使用捆绑程序(推荐),它将自动执行。


5

错误案例:

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

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

输出:

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

修复:您缺少分号(;)来分隔表达式

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

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

3

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

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

原来Unity(emscripten?)不喜欢这种语法。我们用一个很好的旧循环替换它,它立即停止抱怨。我真的很讨厌它没有显示出它抱怨的内容,但是无论如何,还是让我两次蒙羞。


我的猜测是您的问题与此有关
Brandito

这与问题所涉及的情况不同。
CherryDT

@CherryDT不是,因为我得到的错误是完全相同的。
tfrascaroli

不,这个问题是关于由于语句和(下一行之间不存在分号而导致的意外调用某些函数而导致的错误。我看不到您的情况。问题不仅包括标题!
CherryDT

1

当我创建一个新的ES2015类(其中属性名称等于方法名称)时,就遇到了这个问题。

例如:

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

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

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

请注意,此实现在NodeJS 6.10中。

解决方法(如果您不想使用无聊的“ setTest”方法名称),则可以在“ private”属性(如_test)中使用前缀。

jsfiddle中打开您的开发人员工具。


这与问题所涉及的情况不同。
CherryDT

0
  **Error Case:**

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

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

输出:TypeError:(中间值)(中间值)不是一个函数*如何修复它->因为缺少半角可兰(;)来分隔表达式;

 **Fixed**


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

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

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


0

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

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

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

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

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

let add = new CC;
console.log(add.x(4));
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.