Uncaught TypeError: (valore intermedio) (…) non è una funzione


128

Tutto funziona bene quando ho scritto la logica js in una chiusura come un singolo file js, come:

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

ma quando provo a inserire una funzione alternativa di registrazione prima di quella chiusura nello stesso file 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)

si lamenta della presenza di un TypeError:

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

Cos'ho fatto di sbagliato?

Risposte:


275

L'errore è il risultato del punto e virgola mancante sulla terza riga:

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

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

La specifica ECMAScript ha regole specifiche per l'inserimento automatico del punto e virgola , tuttavia in questo caso non viene inserito automaticamente un punto e virgola perché l'espressione tra parentesi che inizia sulla riga successiva può essere interpretata come un elenco di argomenti per una chiamata di funzione.

Ciò significa che senza quel punto e virgola, la window.Glogfunzione anonima veniva invocata con una funzione come msgparametro, seguita dalla (window)quale successivamente tentava di richiamare tutto ciò che veniva restituito.

Ecco come veniva interpretato il codice:

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

4
@armnotstrong Josh è stato più veloce e la risposta è la stessa :)
mrlew

1
Grazie Signore! Il mio linter ha rimosso automaticamente il punto e virgola e tutto si è rotto :)
Jonas Lomholdt

1
eccezionale!!! Grazie mille!! Ho quasi perso tutti i capelli su questo ...
TMS

1
Questo, amico mio, è oro!
LihO

1
questo è folle e sono così grato per questo post. Stavo impostando lo stato dopo ifun'istruzione in una useEffect()funzione React quando continuavo a ricevere questo errore "... non è una funzione".
Rahul Nath,

7

Per rendere semplici le regole del punto e virgola

Ogni riga che inizia con un (, [, `o qualsiasi operatore (/, +, - sono gli unici validi), deve iniziare con un punto e virgola.

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

Questo impedisce a

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

monstrocity.

Nota aggiuntiva

Per menzionare cosa succederà: le parentesi indicheranno, le parentesi saranno trattate come parametri di funzione. Il backtick si trasformerebbe in un modello con tag e le espressioni regolari o gli interi firmati in modo esplicito si trasformeranno in operatori. Ovviamente puoi semplicemente aggiungere un punto e virgola alla fine di ogni riga. È bene tenerlo presente quando si esegue rapidamente la prototipazione e si lascia cadere il punto e virgola.

Inoltre, l'aggiunta di punti e virgola alla fine di ogni riga non ti aiuterà con quanto segue, quindi tieni presente affermazioni come

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.

Il caso sopra accadrà per tornare / continuare / interrompere / ++ / -. Qualsiasi linter lo rileverà con codice morto o errore di sintassi ++ / - (++ / - non accadrà mai realisticamente).

Infine, se vuoi che la concatenazione dei file funzioni, assicurati che ogni file termini con un punto e virgola. Se stai usando un programma bundler (consigliato), dovrebbe farlo automaticamente.


5

Caso di errore:

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

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

Produzione:

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

Correzione: manca un punto e virgola (;) per separare le espressioni

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

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

3

Per me è stato molto più semplice ma mi ci è voluto un po 'per capirlo. Fondamentalmente avevamo nel nostro .jslib

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

Si scopre che a Unity (emscripten?) Non piace quella sintassi. L'abbiamo sostituito con un buon vecchio for-loop e ha smesso di lamentarsi subito. Odio davvero che non mostri la linea di cui si lamenta, ma comunque, ingannami due volte, vergognami.


la mia ipotesi è che il tuo problema avesse qualcosa a che fare con questo
Brandito

Questo è un caso diverso da quello di cui tratta la domanda.
CherryDT

@CherryDT non lo è, poiché l'errore che stavo ricevendo era lo stesso identico.
tfrascaroli

No, questa domanda riguarda gli errori che si ottengono chiamando accidentalmente qualcosa come una funzione a causa della mancanza di un punto e virgola tra l'istruzione e a (nella riga successiva. Non vedo niente di tutto questo nel tuo caso. La domanda non consiste solo nel titolo!
CherryDT

1

Ho riscontrato questo problema quando ho creato una nuova classe ES2015 in cui il nome della proprietà era uguale al nome del metodo.

per esempio:

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

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

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

Si noti che questa implementazione era in NodeJS 6.10.

Come soluzione alternativa (se non si desidera utilizzare il noioso nome del metodo "setTest"), è possibile utilizzare un prefisso per le proprietà "private" (come _test).

Apri i tuoi Strumenti per sviluppatori in jsfiddle .


Questo è un caso diverso da quello di cui tratta la domanda.
CherryDT

0
  **Error Case:**

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

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

Output: TypeError: (valore intermedio) (valore intermedio) non è una funzione * Come risolvere il problema -> perché ti manca il semi colan (;) per separare le espressioni;

 **Fixed**


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

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

perché arriva questo errore ?? Motivo: regole specifiche per l'inserimento automatico del punto e virgola a cui vengono forniti gli standard ES6


0

Quando creo una classe radice, i cui metodi ho definito utilizzando le funzioni freccia. Durante l'ereditarietà e la sovrascrittura della funzione originale ho notato lo stesso problema.

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

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

questo viene risolto definendo il metodo della classe genitore senza funzioni freccia

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

let add = new CC;
console.log(add.x(4));
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.