Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript named function definition executed when it shouldn't

Tags:

javascript

I have no idea what is happening here. The code is:

  if( true ) { 

      console.log('In first function definition');

      function test(){
        console.log('Hello world');
      }

    } else {

      console.log('In the second function definition');

      function test(){
        console.log('Goodbye world');
      }

    }

  test();

I would expect this to log in the console:

'In the first function definition'
'Hello world'

But instead it logs:

'In the first function definition'
'Goodbye world'

How is the second named function being created when the code doesn't enter that branch?

like image 926
BIOS Avatar asked Jun 05 '13 02:06

BIOS


People also ask

Can a function be executed without being called?

It is also common to say "call upon a function", "start a function", or "execute a function". In this tutorial, we will use invoke, because a JavaScript function can be invoked without being called.

Can a declared function be called before it has been declared in the script?

For example: function myFunction() { // do something }; As you can see, the function name ( myFunction ) is declared when the function is created. This means that you can call the function before it is defined.

Do JavaScript functions need to be defined before they are called?

JavaScript is an interpreted language: the interpreter runs and executes the program sequentially, therefore, functions have to be defined before they're called.

Why is JavaScript saying my function is not defined?

Function is not defined | JavaScript The reason for getting the error is very simple. The error occurs if you try to make a function call that you haven't defined. In the above code example, we did exactly the same thing, we called a function named sum(), which is not defined.


2 Answers

Remember, everything in JavaScript is function-scoped; there is no block scope.

To that effect, you have two function declarations defined in the same scope (whatever the scope that if-else sits in), with the same name, in different blocks. This produces inconsistent results between browsers.

You need to either give those functions different names, or use function expressions, with something like this:

var f;
if(true) { 
   console.log('In first function definition');

   f = function(){
     console.log('Hello world');
   };

} else {
  console.log('In the second function definition');

  f = function(){
    console.log('Goodbye world');
  };
}
f();

To your excellent question of

But how is the function defined, if we don't enter that branch of the code? If that block is not executed, why is scope a consideration?

The simple answer is that function declarations are "hoisted", and immediately available anywhere in the scope, even before the declaration itself.

ie:

function foo(){
    f(); //perfectly valid

    function f(){
    }
}

The longer answer is that, prior to entering the scope, all variable declarations, and function declarations are stripped out, and placed onto the "activation object." The activation object is then placed at the head of the "scope chain." When you execute the function, any references to these variables and functions are simply resolved from there.

like image 152
Adam Rackis Avatar answered Oct 03 '22 03:10

Adam Rackis


Function definitions in javascript are independent of control structures, meaning that when you redefine the function the second time even though it's in a branch of a control structure that will never bit hit it still redefines the function. What are you trying to do anyway?

like image 38
Bad Wolf Avatar answered Oct 03 '22 02:10

Bad Wolf