23

I have a JavaScript code block like below in my html page. When I run this by loading the page. I am getting below output on my browser console.

outer world 
Uncaught TypeError: undefined is not a function

As you can see in the code snippet, I am not executing the function named b anywhere in the code. But on running the code, the output from that function is coming along with an undefined is not a function error which I could not locate anywhere in my code block.

To add more to this scenario, there is no logs when I remove any one of the parts in the code. that is. If I remove b's initialization from the code then there are no errors and output. Also if I remove the self executing function block, there are no logs or errors. Its true that the b's initialization line is missing a semicolon. but what tempts it to provide such an output confuses me. Would you help me out to figure out a reasoning for this behaviour?

Can you please help me understand why it is happening so?

var b = function() {
  console.log('outer world');
}

(function() { 

})();
Robert Harvey
  • 168,684
  • 43
  • 314
  • 475
Mithun Satheesh
  • 25,056
  • 14
  • 73
  • 97

2 Answers2

32

Missed a ; after declaring b. The following code is equivalent to what you have.

var b = function() {
   console.log ('outer world');
}(function() {})();

Without the ; b becomes self-executing and takes an empty function as a parameter. After that it self-executes again; however, because b does not return a function, you get an exception.

I suggest not to skip ; until you become js ninja :). Keep b inside to avoid global scope pollution.

(function () {
    "use strict";

    var b = function () {
        console.log("hi");
    };
    // other code
}());

Semicolon auto-insertion discussion

In case you do not want semicolons, add an operator before self-running function

var b = function () { console.log('outer world') }
;(function() { /* ... */ }())

ES6 Update:

(() => {
  const b = () => console.log('hi')
  // ...
})()
kornieff
  • 2,021
  • 15
  • 27
  • 6
    Finally, an example where Javascript doesn't automatically insert a semicolon where it looks intuitive to add it! – Barmar Sep 17 '14 at 07:05
  • 5
    Anything that starts with `(` or `[` needs `;` before it. – kornieff Sep 17 '14 at 07:06
  • Yes. this helps me understand the scenario. Will you encorporate the links that Barmar provided in Rickard Staaf's answer. It helped me to understand it more. – Mithun Satheesh Sep 17 '14 at 07:20
  • 1
    @mithunsatheesh, http://stackoverflow.com/questions/2846283/what-are-the-rules-for-javascripts-automatic-semicolon-insertion-asi most likely lists all the cases. I did learn a few for sure. But the point is that although skipping `;` can make code look a bit cleaner, it will sure take more time and anger to debug. – kornieff Sep 17 '14 at 07:25
5

You need a semicolon after your var declaration, and by the way, please remove the space between log and (

var b = function() {
       console.log('outer world');
};
Rickard Staaf
  • 2,380
  • 2
  • 11
  • 13
  • can you provide an explanation when we drop the semi colon how does it give such an output. What happened in background that i dont have in my code?. I dint execute b at any point – Mithun Satheesh Sep 17 '14 at 07:02
  • Read @kornieff's answer. And see http://stackoverflow.com/questions/2846283/what-are-the-rules-for-javascripts-automatic-semicolon-insertion-asi – Barmar Sep 17 '14 at 07:06
  • It will try to execute your defined function that outputs console.log, and send it the parameter of a new anonymous function, then at the end you are trying to execute a function that does not exist, because what you have at that point is not a function anymore. – Rickard Staaf Sep 17 '14 at 07:07
  • @RickardStaaf : +1. thanks for the answer. However , kornieff's explanation was kind of what i was looking for. Sorry that could not phrase my question in a better way. – Mithun Satheesh Sep 17 '14 at 07:24
  • @RickardStaaf, +1 for being faster than me :) – kornieff Sep 17 '14 at 07:38