Domanda di associatività Javascript "Uncaught TypeError: object is not a function"


92

Il codice è il seguente:

<body>
    <a href="javascript:;" id="test">hello</a>
</body>

<script type="text/javascript">
    document.getElementById("test").addEventListener("click", function () {
      test()
    }, false)
    function test() {
      var postTypes = new Array('hello', 'there')   
      (function() { alert('hello there') })()
    }
</script>

Questo lancerà un:

"Errore di tipo non rilevato: l'oggetto non è una funzione"

Se racchiudo la chiamata / invocazione della funzione anonima in un altro set di parentesi, verrà eseguito l'avviso, ma mi darà comunque un errore. Se metto un punto e virgola dopo la definizione "var postTypes" allora andrà benissimo.

Sono stato portato a credere che javascript non richieda i punti e virgola, quindi sto ipotizzando che ci siano alcune strane regole di associatività dell'applicazione delle funzioni che non comprendo appieno. Perché ricevo questo errore?


Sembra quasi che tu stia cercando di creare sia una funzione anonima che una funzione statica e aspettandoti che venga eseguita come una sola. Cosa succede se rimuovi function ()
brumScouse

Risposte:


85

JavaScript non richiede punti e virgola, è solo che l'interprete li inserirà per te nelle interruzioni di riga ove possibile * .

Sfortunatamente, il codice

var a = new B(args)(stuff)()

non non provocare un errore di sintassi, quindi non ;verrà inserito. (Un esempio che può essere eseguito è

var answer = new Function("x", "return x")(function(){return 42;})();

Per evitare sorprese come questa, allenati a concludere sempre una dichiarazione con ;.


* Questa è solo una regola pratica e non sempre vera. La regola di inserimento è molto più complicata. Questa pagina del blog sull'inserimento del punto e virgola ha più dettagli.


13
Oppure: Per evitare sorprese come questa, allenati a scrivere codice leggibile pulito (che dovrebbe sempre valere) e conosci le regole generali ASI ... non è davvero diverso dal "sapere" come funzionano le chiusure in JS.

18

Il codice presenta un caso in cui il processo di inserimento automatico del punto e virgola (ASI) non viene eseguito.

Non dovresti mai fare affidamento sull'ASI. È necessario utilizzare il punto e virgola per separare correttamente le istruzioni:

var postTypes = new Array('hello', 'there'); // <--- Place a semicolon here!!

(function() { alert('hello there') })();

Il tuo codice stava effettivamente cercando di richiamare l'oggetto array.


Un modo per risolvere il problema, ma non riesco a stare dietro al Crockford-club.

1
@pst: Mi permetta di riformulare, non sono in Crock's-club a tutti :)
Christian C. Salvadó

In tal caso mi scuso per le parole dure :(

Mi è piaciuto il quiz. ASI è davvero terribilmente confuso con icky-code!

8

Ho ricevuto un errore simile e mi ci è voluto un po 'per capire che nel mio caso ho chiamato la variabile di array payInvoices e anche la funzione payInvoices. Ha confuso AngularJs. Dopo aver cambiato il nome in processPayments (), finalmente ha funzionato. Volevo solo condividere questo errore e questa soluzione poiché mi ci è voluto molto tempo per capirlo.


Lo stesso qui, avevo una variabile denominata alerte stavo cercando di chiamare la funzione di avviso javascript e avrebbe detto "avviso non è una funzione". alert
Stava

0

Prova ad avere il corpo della funzione prima della chiamata della funzione nel tuo file JavaScript.


0

Stavo ricevendo lo stesso errore e ho passato un giorno e mezzo a cercare una soluzione. La risposta di Naomi mi ha portato alla soluzione di cui avevo bisogno.

Il mio input (tipo = pulsante) aveva un attributo nameidentico al nome di una funzione che veniva chiamato dall'evento onClick. Una volta cambiato l'attributo, nametutto ha funzionato.

<input type="button" name="clearEmployer" onClick="clearEmployer();">

cambiato in:

<input type="button" name="clearEmployerBtn" onClick="clearEmployer();">

0

Ho questo errore durante la compilazione e il raggruppamento di TS con WebPack. Viene compilato export class AppRouterElement extends connect(store, LitElement){....}in let Sr = class extends (Object(wr.connect) (fn, vr)) {....}cui sembra sbagliato a causa della virgola mancante. Durante il raggruppamento con Rollup, nessun errore.

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.