TypeError não capturado: (valor intermediário) (…) não é uma função


128

Tudo funciona bem quando escrevi a lógica js em um fechamento como um único arquivo js, ​​como:

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

mas quando tento inserir uma função alternativa de log antes desse fechamento no mesmo arquivo 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)

reclama que existe um TypeError:

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

O que eu fiz errado?

Respostas:


275

O erro é resultado do ponto e vírgula ausente na terceira linha:

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

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

A especificação ECMAScript possui regras específicas para inserção automática de ponto e vírgula , no entanto, nesse caso, um ponto e vírgula não é inserido automaticamente porque a expressão entre parênteses que começa na próxima linha pode ser interpretada como uma lista de argumentos para uma chamada de função.

Isso significa que, sem esse ponto-e-vírgula, a window.Glogfunção anônima estava sendo chamada com uma função como msgparâmetro, seguida pela (window)qual tentava posteriormente invocar o que foi retornado.

É assim que o código estava sendo interpretado:

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

4
@armnotstrong Josh foi mais rápido, e a resposta é a mesma :)
mrlew

1
Obrigado senhor! Meu linter removido o ponto e vírgula automagicamente e tudo quebrou :)
Jonas Lomholdt

1
impressionante!!! Muito obrigado!! Eu quase perdi todo o meu cabelo em um presente ...
TMS

1
Isso, meu amigo, é ouro!
Liho

1
isso é insano e estou muito agradecido por este post. Eu estava definindo o estado após uma ifdeclaração em uma useEffect()função React quando recebi o erro "... não é uma função".
Rahul Nath

7

Para simplificar as regras de ponto e vírgula

Cada linha que começa com um (, [, `, ou qualquer operador (/, +, - são os únicos válidos), deve começar com um ponto e vírgula.

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

Isso impede que um

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

monstruosidade.

Nota adicional

Para mencionar o que acontecerá: colchetes serão indexados, parênteses serão tratados como parâmetros de função. O backtick se transformaria em um modelo marcado e regex ou números inteiros assinados explicitamente se transformarão em operadores. Obviamente, você pode adicionar um ponto-e-vírgula ao final de cada linha. No entanto, é bom ter em mente quando você está fazendo prototipagem rápida e diminuindo seu ponto e vírgula.

Além disso, adicionar ponto-e-vírgula ao final de cada linha não ajudará no seguinte, portanto, lembre-se de declarações como

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.

O caso acima retornará / continuará / interromperá / ++ / -. Qualquer linter irá capturar isso com código morto ou erro de sintaxe ++ / - (++ / - nunca acontecerá realisticamente).

Por fim, se você deseja que a concatenação de arquivos funcione, verifique se cada arquivo termina com um ponto e vírgula. Se você estiver usando um programa de empacotador (recomendado), ele deve fazer isso automaticamente.


5

Caso de erro:

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

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

Resultado:

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

Correção: falta um ponto-e-vírgula (;) para separar as expressões

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

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

3

Para mim, era muito mais simples, mas demorei um pouco para descobrir. Basicamente, tivemos em nosso .jslib

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

Acontece que o Unity (emscripten?) Simplesmente não gosta dessa sintaxe. Nós o substituímos por um bom loop for-old e ele parou de reclamar imediatamente. Eu realmente odeio que ele não mostre a linha da qual está reclamando, mas enfim, me engane duas vezes com vergonha.


meu palpite é que o problema era algo a ver com isso
Brandito

Este é um caso diferente do que trata a questão.
CherryDT 3/07

@CherryDT não é, já que o erro que eu estava recebendo era exatamente o mesmo.
tfrascaroli 03/07

Não, esta pergunta é sobre erros que você obtém ao chamar acidentalmente algo como uma função, devido ao ponto e vírgula existente entre a instrução e a (na próxima linha. Não vejo nada disso no seu caso. A questão não consiste apenas no seu título!
CherryDT 3/07

1

Eu enfrentei esse problema quando criei uma nova classe ES2015 em que o nome da propriedade era igual ao nome do método.

por exemplo:

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

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

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

Observe que esta implementação estava no NodeJS 6.10.

Como solução alternativa (se você não quiser usar o chato nome do método 'setTest'), use um prefixo para as propriedades 'particulares' (como _test).

Abra as Ferramentas do desenvolvedor no jsfiddle .


Este é um caso diferente do que trata a questão.
CherryDT 3/07

0
  **Error Case:**

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

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

Saída: TypeError: (valor intermediário) (valor intermediário) não é uma função * Como corrigir IT -> porque falta a semicolana (;) para separar expressões;

 **Fixed**


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

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

por que esse erro vem ?? Razão: regras específicas para inserção automática de ponto-e-vírgula que recebem padrões ES6


0

Quando crio uma classe raiz, cujos métodos defini usando as funções de seta. Ao herdar e substituir a função original, notei o mesmo problema.

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

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

isso é resolvido definindo o método da classe pai sem as funções de seta

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

let add = new CC;
console.log(add.x(4));
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.