The code is as follows:

<body> <a href="javascript:;">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> 

This will throw an:

"Uncaught TypeError: object is not a function"

If I wrap the anonymous function call/invocation in another set of parentheses it will execute the alert, but still give me an error. If I put a semicolon after the "var postTypes" definition then it will be completely fine.

I was led to believe that JavaScript does not require semicolons, so I'm making a guess that there is some weird associativity rules of function application that I am not fully understanding. Why am I getting this error?

1

7 Answers

JavaScript does require semicolons. It's just that the interpreter will insert them for you on line breaks where possible*.

Unfortunately, the code

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

does not result in a syntax error, so no ; will be inserted. (An example which can run is

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

To avoid surprises like this, train yourself to always end a statement with ;.


* This is just a rule of thumb and not always true. The insertion rule is much more complicated. This blog page about semicolon insertion has more detail.

1

Your code experiences a case where the automatic semicolon insertion (ASI) process doesn't happen.

You should never rely on ASI. You should use semicolons to properly separate statements:

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

Your code was actually trying to invoke the array object.

4

I ran into this problem in React: I tried to destructure and use a named export when it was a default export, for example:

// module.js const myFunction = () => null export default myFunction 
// component.js // THIS WAS WRONG: // import { myFunction } from './module' // SHOULD BE THIS: import myFunction from './module' 
3

I got a similar error and it took me a while to realize that in my case I named the array variable payInvoices and the function also payInvoices. It confused AngularJS.

Once I changed the name to processPayments() it finally worked.

1

Try to have the function body before the function call in your JavaScript file.

I was getting this same error and spent a day and a half trying to find a solution. Naomi's answer lead me to the solution I needed.

My input (type=button) had an attribute name that was identical to a function name that was being called by the onClick event. Once I changed the attribute name, everything worked.

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

changed to:

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

I have this error when compiling and bundling TypeScript code with Webpack. It compiles export class AppRouterElement extends connect(store, LitElement){....} into let Sr = class extends (Object(wr.connect) (fn, vr)) {....} which seems wrong because of the missing comma. When bundling with Rollup, no error.