3

In certain circumstances, having more than one self-invoking function in a single JavaScript file provokes an error. Getting the second function to return a value averts the error.

I have a barebones HTML file...

<script src="two.js"></script>
<script src="one.js"></script>

... using these scripts:

// two.js
(function () {
  console.log('1/2')
})()

(function () {
  console.log('2/2')
})()

    

// one.js
(function () {
  console.log('1/1')
})()

When I open the file in Chrome, I get this output:

1/2 two.js:2
Uncaught TypeError: undefined is not a function two.js:6
1/1

Other browsers complain in their own way. In other words, having two self-invoking functions in the same script causes a problem. Having one self-invoking function per script works fine. If I comment out the second function script two.js, there is no problem.

However, if I get the second function to return a value, then there is no problem either. Everything works fine if I change two.js to this:

(function () {
  console.log('1/2')
})()

foo = (function () {
  console.log('2/2')
  return 'bar'
})()

Why does the first version fail and the second succeed?

Jonathan Leffler
  • 666,971
  • 126
  • 813
  • 1,185
James Newton
  • 5,667
  • 5
  • 41
  • 87

2 Answers2

5

You forgot the semicolons:

(function () {
  console.log('1/2')
})();

(function () {
  console.log('2/2')
})();

Otherwise the returned value of the previous expression (undefined) tries to execute the next expression. Obviously undefined is not a function.

In the semicolonless JavaScript world, you'll often see the semicolon preceding any raw expression, such as ():

;(function(){}())
;['1','2','3'].map(Number)

JavaScript will attempt to fill in the semicolons you "forgot" but those expressions are ambiguous so you need to add it.

Community
  • 1
  • 1
elclanrs
  • 85,039
  • 19
  • 126
  • 159
2

You're missing semicolons at the end of your function expressions, so the proceeding parenthetical expression is parsed as a call to the function. Since the function doesn't return a value (return value is implicitly undefined), the code is functionally equivalent to undefined() - hence the error.

Moral of the story - Don't forget your semicolons!

0x499602D2
  • 87,005
  • 36
  • 149
  • 233
  • Well now... This is the very first time that I have encountered a real need for semicolons. You are absolutely right: adding a single semicolon in the right place solves the issue. – James Newton Dec 19 '13 at 01:04
  • @JamesNewton There are other situations in which semicolons are required for the code to work correctly. As a good rule of thumb it is always best to use semicolons just in case. – 0x499602D2 Dec 19 '13 at 01:05