Pytanie asocjacyjne JavaScript „Uncaught TypeError: object is not a function”


95

Kod jest następujący:

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

Spowoduje to wyświetlenie:

„Uncaught TypeError: obiekt nie jest funkcją”

Jeśli zawinę anonimowe wywołanie / wywołanie funkcji w inny zestaw nawiasów, uruchomi alert, ale nadal wyświetli błąd. Jeśli wstawię średnik po definicji „var postTypes”, wszystko będzie dobrze.

Doszedłem do wniosku, że javascript nie wymaga średników, więc domyślam się, że istnieją dziwne reguły asocjacyjne aplikacji funkcji, których nie do końca rozumiem. Dlaczego otrzymuję ten błąd?


Wygląda na to, że próbujesz utworzyć zarówno funkcję anonimową, jak i statyczną i oczekujesz, że będzie ona wykonywana jako jedna. Co się stanie, jeśli usuniesz function ()
brumScouse

Odpowiedzi:


88

JavaScript wymaga średników, po prostu interpreter wstawi je za Ciebie na podziałach wierszy, jeśli to możliwe * .

Niestety kod

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

ma nie powodować błąd składni, więc nie ;zostanie wstawiony. (Przykładem, który można uruchomić, jest

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

Aby uniknąć takich niespodzianek, naucz się zawsze kończyć wypowiedź ;.


* To tylko praktyczna zasada i nie zawsze jest prawdą. Reguła wstawiania jest znacznie bardziej skomplikowana. Ta strona bloga dotycząca wstawiania średników zawiera więcej szczegółów.


13
Albo: Aby uniknąć takich niespodzianek, wyćwicz się w pisaniu czystego, czytelnego kodu (który zawsze powinien mieć zastosowanie) i poznaj ogólne zasady ASI… tak naprawdę nie różni się to od „wiedzy”, jak działają domknięcia w JS.

18

Twój kod napotyka przypadek, w którym nie występuje proces automatycznego wstawiania średnika (ASI).

Nigdy nie powinieneś polegać na ASI. Do prawidłowego oddzielenia instrukcji należy używać średników:

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

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

Twój kod faktycznie próbował wywołać obiekt tablicy.


To jeden ze sposobów na rozwiązanie problemu, ale nie mogę stać za klubem Crockford.

1
@pst: Pozwólcie, że powtórzę, w ogóle nie jestem w klubie Crocka :)
Christian C. Salvadó

W takim razie przepraszam za ostre słowa :(

Podobał mi się quiz. ASI jest rzeczywiście strasznie mylące z okropnym kodem!

8

Otrzymałem podobny błąd i chwilę zajęło mi uświadomienie sobie, że w moim przypadku nazwałem zmienną tablicową payInvoices, a funkcję również payInvoices. To zdezorientowało AngularJs. Po zmianie nazwy na processPayments () w końcu zadziałało. Chciałem tylko udostępnić ten błąd i rozwiązanie, ponieważ jego rozwiązanie zajęło mi dużo czasu.


To samo tutaj, miałem zmienną o nazwie alerti próbowałem wywołać funkcję ostrzegania javascript i powiedziałoby: „alert nie jest funkcją”. Próbował wywołać alertzmienną zamiast rzeczywistej funkcji
James111

0

Postaraj się, aby treść funkcji przed wywołaniem funkcji znajdowała się w pliku JavaScript.


0

Otrzymywałem ten sam błąd i spędziłem półtora dnia próbując znaleźć rozwiązanie. Odpowiedź Naomi doprowadziła mnie do rozwiązania, którego potrzebowałem.

Moje dane wejściowe (przycisk type =) miały atrybut nameidentyczny z nazwą funkcji, która była wywoływana przez zdarzenie onClick. Po zmianie atrybutu namewszystko działało.

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

zmienić na:

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

0

Mam ten błąd podczas kompilowania i łączenia TS z WebPack. Kompiluje się export class AppRouterElement extends connect(store, LitElement){....}w let Sr = class extends (Object(wr.connect) (fn, vr)) {....}który wydaje się zły z powodu braku przecinka. Podczas łączenia za pomocą pakietu zbiorczego nie ma błędu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.