【问题标题】:Uncaught TypeError: (intermediate value)(...) is not a functionUncaught TypeError: (intermediate value)(...) is not a function
【发布时间】:2021-12-16 11:47:56
【问题描述】:

当我在闭包中将 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

我做错了什么?

【问题讨论】:

标签: javascript typeerror


【解决方案1】:

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

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

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

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

这意味着,如果没有该分号,匿名 window.Glog 函数将被调用,并使用一个函数作为 msg 参数,然后是 (window),后者随后试图调用返回的任何内容。

这就是代码的解释方式:

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

【讨论】:

  • @armnotstrong Josh 更快,答案是一样的 :)
  • 谢谢先生!我的 linter 自动删除了分号,一切都坏了:)
  • 太棒了!!!太感谢了!!我几乎把头发都掉光了……
  • 我的朋友,这是金子!
  • 这太疯狂了,我非常感谢这篇文章。当我不断收到此“...不是函数”错误时,我在 React useEffect() 函数中的 if 语句之后设置状态。
【解决方案2】:

错误案例:

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】:
      **Error Case:**
    
    var handler = function(parameters) {
      console.log(parameters);
    }
    
    (function() {     //IIFE
     // some code
    })();
    

    输出:TypeError: (intermediate value)(intermediate value) is not a function *如何修复 IT -> 因为您缺少分号 (;) 来分隔表达式;

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

    为什么会出现这个错误? 原因 : specific rules for automatic semicolon insertion which is given ES6 stanards

    【讨论】:

      【解决方案4】:

      我在创建属性名称与方法名称相同的新 ES2015 类时遇到了这个问题。

      例如:

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

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

      作为一种解决方法(如果您不想使用无聊的“setTest”方法名称),您可以为您的“私有”属性使用前缀(例如_test)。

      jsfiddle 中打开您的开发者工具。

      【讨论】:

      • 这与问题所在的情况不同。
      【解决方案5】:

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

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

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

      【讨论】:

      • 我猜你的问题与this有关
      • 这与问题所在的情况不同。
      • @CherryDT 它不是,因为我得到的错误是完全相同的。
      • 不,这个问题是关于由于语句和下一行的( 之间不存在分号而意外调用函数而导致的错误。在你的情况下,我没有看到任何这些。问题不仅包括它的标题!
      【解决方案6】:

      使分号规则简单

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

      就是这样。完成。

      • 请注意,/、+、- 是您无论如何都希望这样做的唯一有效运算符。您永远不会希望行以 '*' 开头,因为它是一个二进制运算符,在行首永远不会有意义。

      为什么?

      考虑以下几点:

      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
      

      附加说明

      提一下会发生什么:括号将索引,括号将被视为函数参数。反引号将转换为tagged template,正则表达式将转换为除法,显式 +/- 有符号整数将转换为加/减运算符。

      当然,您可以通过在每个换行符的末尾添加一个分号来避免这种情况,但不要相信这样做可以让您像 C 程序员一样编写代码。因为当您以分号结束一行时,Javascript 可能会根据您的意愿隐含地为您添加一个分号。所以,请记住像

      这样的语句
      return       // Implicit semicolon, will return undefined.
          (1+2);
      
      i        // Implicit semicolon on this line
         ++;   // But, if you really intended "i++;"
               // and you wrote it like this,
               // you need help.
      

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

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

      【讨论】:

        【解决方案7】:

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

        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));
        

        【讨论】:

        • Function.bind 也需要这个策略——谢谢
        【解决方案8】:

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

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

        并且在car 声明的末尾仅添加一个;,错误就会消失:

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

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

        【讨论】:

          【解决方案9】:

          我的情况:(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 的导入

          【讨论】:

            猜你喜欢
            • 2021-08-13
            • 1970-01-01
            • 2021-07-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多