Javascript "Uncaught TypeError: объект не является функцией" вопрос ассоциативности

Код выглядит следующим образом:

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

Это бросит:

"Uncaught TypeError: объект не является функцией"

Если я заключу анонимный вызов/вызов функции в другой набор скобок, он выдаст предупреждение, но все равно выдаст ошибку. Если после определения "var postTypes" поставить точку с запятой, то все будет в порядке.

Я был убежден, что javascript не требует точек с запятой, поэтому я предполагаю, что есть некоторые странные правила ассоциативности применения функций, которые я не до конца понимаю. Почему я получаю эту ошибку?

Ответ 1

Javascript действительно требует точек с запятой, просто интерпретатор вставит его для вас в разрывы строк, когда код станет без синтаксической ошибки *.

К сожалению, код

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

не является синтаксической ошибкой, поэтому ; вставляться не будет. (Пример, который можно запустить:

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

Чтобы избежать подобных сюрпризов, приучите себя всегда заканчивать утверждение ;.

(*: Просто правило большого пальца. Не всегда верно. Правило вставки намного сложнее. На этой странице блога о вставке точек с запятой более подробно.)

Ответ 2

В вашем коде присутствует случай, когда процесс Автоматическая точка с запятой (ASI) не выполняется.

Вы никогда не должны полагаться на ASI. Вы должны использовать точки с запятой для правильного разделения операторов:

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

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

Ваш код фактически пытался вызвать объект массива.

Ответ 3

У меня была аналогичная ошибка, и мне потребовалось некоторое время, чтобы понять, что в моем случае я назвал переменную переменной payInvoices и функцию payinvoices. Он смутил AngularJs. Как только я сменил имя на processPayments(), он наконец-то сработал. Просто хотел поделиться этой ошибкой и решением, поскольку мне потребовалось много времени, чтобы понять это.

Ответ 4

Попробуйте иметь тело функции перед вызовом функции в вашем файле JavaScript.

Ответ 5

Я получал эту же ошибку и полтора дня пытался найти решение. Наоми ответ приведет меня к решению, в котором я нуждаюсь.

Мой ввод (type = button) имел атрибут name, который был идентичен имени функции, вызываемой событием onClick. Как только я изменил атрибут name, все заработало.

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

изменено на:

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