当我把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

我做错了什么?


当前回答

我的例子:(Angular, PrimeNG)

我的错误: 我的版本:

 "@angular/animations": "^12.2.0",
 "@angular/cdk": "^12.2.0",
 "@angular/common": "^12.2.0",
 "@angular/compiler": "^12.2.0",
 "@angular/core": "^12.2.0",
 "@angular/forms": "^12.2.0",
 "@angular/platform-browser": "^12.2.0",
 "@angular/platform-browser-dynamic": "^12.2.0",
 "@angular/router": "^12.2.0",
 "primeng": "^13.0.0-rc.2",
 "quill": "^1.3.7"

我的解决方案: node_modules / primeng fesm2015 / primeng-editor.mjs

如图所示,更新Quill的导入

其他回答

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

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

({ color, capacity, brand } = car);

而只是一个;在汽车声明结束时,错误消失:

let car = {
  brand: 'benz',
  capacity: 80,
  color: 'yellow',
}; // <-------------- here a semicolon is needed

实际上,之前({颜色,容量,品牌}=汽车);需要看到分号。

错误案例:

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;

使分号规则简单

以(,[,',或任何算术运算符开头的每一行,如果您希望它被解释为自己的行,必须以分号开头~否则,它可能会意外地与前一行合并。所有其他换行符都有隐式分号。

就是这样。完成了。

Note that /, +, - are the only valid operators you would want to do this for anyway. You would never want a line to begin with '*', since it's a binary operator that could never make sense at the beginning of a line. You should put the semicolons at the start of the line when doing this. You should not try to "fix" the issue by adding a semicolon to the previous line, or any reordering or moving of the code will cause the issue to potentially manifest again. Many of the other answers (including top answers) make this suggestion, but it's not a good practice.


为什么这些特殊的字符需要开头的分号?

考虑以下几点:

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将转换为除法,显式的+/-符号整数将转换为正负运算符。

当然,您可以通过在每个换行符的末尾添加分号来避免这种情况,但不要相信这样做可以让您像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都会捕捉到带有死代码的前一种情况,或者带有++/——语法错误的后一种情况。

最后,如果您希望文件连接工作,请确保每个文件以分号结束。如果您正在使用捆绑程序(推荐),它应该自动执行此操作。

如果来自Ionic Angular,则更新到最新版本

ng update @ionic/angular

该错误是由于第三行缺少分号造成的:

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

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

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

这意味着没有分号,匿名窗口。Glog函数被调用时使用一个函数作为msg参数,后面跟着(window),它随后试图调用返回的任何东西。

下面是代码的解释:

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