Can You Find The Bug in This Code?

vzhou842

Victor Zhou

Posted on April 3, 2019

Can You Find The Bug in This Code?

Here’s a bit of Javascript that prints “Hello World!” on two lines:

(function() {
  (function() {
    console.log('Hello')
  })()

  (function() {
    console.log('World!')
  })()
})()

…except it fails with a runtime error. Can you spot the bug without running the code?

Scroll down for a hint.






Hint

Here’s the text of the error:

TypeError: (intermediate value)(...) is not a function

What’s going on?

Scroll down for the solution.






Solution

One character fixes this code:

(function() {
  (function() {
    console.log('Hello')
  })();
  (function() {
    console.log('World!')
  })()
})()

Without that semicolon, the last function is interpreted as an argument to a function call. Here’s a rewrite that demonstrates what’s going on when the code is run without the semicolon:

const f1 = function() { console.log('Hello'); };
const f2 = function() { console.log('World!'); };

f1()(f2)();

There are 3 function invocations in that last line:

  • f1 is called with no arguments
  • The return value of f1() is called with f2 as its only argument
  • The return value of f1()(f2) is called with no arguments

Since the return value of f1() is not a function, the runtime throws a TypeError during the second invocation.

With the semicolon added, this becomes:

const f1 = function() { console.log('Hello'); };
const f2 = function() { console.log('World!'); };

f1();(f2)();

Which runs as expected.

Wait, you had this bug once?

Yup.

Why would you ever write code with so many Immediately Invoked Function Expressions (IIFE)?

It’s a long story - this post explains how I wrote bad enough code to have this bug.

The Lesson

Always use semicolons. This specific case was a bit contrived, but something similar could happen to you. Here’s another Hello World program that fails for a related reason:

const a = 'Hello'
const b = 'World' + '!'
[a, b].forEach(s => console.log(s))

I’ll leave figuring this one out as an exercise for you.

Most Javascript style guides require semicolons, including Google’s, Airbnb’s, and jQuery’s. To summarize: always use semicolons.

💖 💪 🙅 🚩
vzhou842
Victor Zhou

Posted on April 3, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Can You Find The Bug in This Code?
javascript Can You Find The Bug in This Code?

April 3, 2019