未捕获的类型错误:(中间值)(…)不是函数
当我将 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
我做错了什么?
此错误是由于第三行缺少分号造成的:
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);
简化分号规则
如果希望将以
(
、
[
、` 或任何算术运算符开头的每一行解释为自己的行,则必须以分号开头 ~ 否则,它可能会意外地与前一行合并。所有其他换行符都有隐式分号。
就是这样。完成。
-
请注意,/、+、- 是您希望执行此操作的唯一有效运算符。您永远不会希望一行以“*”开头,因为它是一个二进制运算符,在行首永远没有意义。
-
执行此操作时,应将分号放在行的开头。您不应尝试通过在前一行中添加分号或进行任何重新排序来“修复”此问题或移动代码可能会导致问题再次出现。许多其他答案(包括最佳答案)都提出了这个建议,但这不是一个好的做法。
为什么这些特定字符需要以分号开头?
考虑以下内容:
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
附加说明
提及会发生什么:括号将索引,圆括号将被视为函数参数。反引号将转换为 带标签的模板 ,正则表达式将转换为除法,显式 +/- 有符号整数将转换为加/减运算符。
当然,您可以通过在每个换行符末尾添加分号来避免这种情况,但 不要 相信这样做可以让您像 C 程序员一样编码。因为当您 不 用分号结束一行时,Javascript 可能会违背您的意愿为您隐式添加一个分号。因此,请记住类似
return // Implicit semicolon, will return undefined.
(1+2);
i // Implicit semicolon on this line
++; // But, if you really intended "i++;"
// and you actually wrote it like this,
// you need help.
的语句,上述情况将发生在 return/continue/break/++/-- 中。任何 linter 都会捕获前一种情况(死代码)或后一种情况(++/-- 语法错误)。
最后,如果您希望文件连接正常工作,请确保每个文件都以分号结尾。如果您使用的是打包程序(推荐),它应该会自动执行此操作。
错误案例:
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;