Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript named function expressions - scope accessibility [duplicate]

I'm following John Resig's Secrets of JS ninja slides and I've found something I don't clearly understand. Following code defines a named function expression:

var ninja = function myNinja(){
  console.log(myNinja); // function myNinja() {...}
};
myNinja; // undefined

As I can see, in the current scope (suppose it's global), ninja is the variable that holds reference to the named function myNinja. ninja variable is accessible in the scope - that's clear, but myNinja is not accessible in the scope (but it's accessible inside its own function). How come?

If I define a function (not using a function expression, but function declaration):

function Cheese() {
  console.log(Cheese);
}

then it's accessible in the current scope. I know that this just works like that - but can someone explain why is that?

like image 769
ducin Avatar asked Jul 03 '13 11:07

ducin


People also ask

What does () => mean in JavaScript?

It's a new feature that introduced in ES6 and is called arrow function. The left part denotes the input of a function and the right part the output of that function.

What is difference between function expression and function declaration?

The main difference between a function expression and a function declaration is the function name, which can be omitted in function expressions to create anonymous functions. A function expression can be used as an IIFE (Immediately Invoked Function Expression) which runs as soon as it is defined.

What is a named function in JavaScript?

Named Functions: In JavaScript, named functions are simply a way of referring to a function that employs the function keyword followed by a name that can be used as a callback to that function. Normal functions with a name or identifier are known as named functions.


2 Answers

In his book, The Secrets of the JavaScript Ninja, John Resig makes a wonderful explanation about this concept.

http://jsninja.com/

Below are the quotes from the book:

4.2.4. Inline named functions

 <script type="text/javascript">
  var ninja = function myNinja(){ 
      assert(ninja == myNinja, "this is named two things at once!"); 
  };
  ninja(); 
  assert(typeof myNinja == "undefined",
    "But myNinja isn't defined outside of the function."); 
 </script>

This listing brings up the most important point regarding inline functions: even though inline functions can be named, those names are only visible within the functions themselves.

Remember the scoping rules we talked about back in chapter 3? Inline function names act somewhat like variable names, and their scope is limited to the function within which they’re declared.

3.2.1. Scoping and functions

Variable declarations are in scope from their point of declaration to the end of the function within which they’re declared, regardless of block nesting.

If you would like to know more about this concept, this book will help you.

like image 128
naota Avatar answered Oct 16 '22 19:10

naota


why is that?

A function expression creates a new function object every time it is evaluated. What happens with that result is irrelevant at first. But…

var ninja;
// myNinja; - what would you expect it to be here?
for (var i=0; i<5; i++)
    ninja = function myNinja(){
        console.log(myNinja);
    };
// myNinja; - *which one* would you expect it to be here?
ninja();

The call to ninja() is obvious, it references the function that was assigned to that variable at last. And the myNinja in the console.log references the current function object - it's in its own scope.

But the myNinja identifier would be ambiguous outside the function itself.

In contrast, a function declaration is hoisted and accessible from the whole scope. Its identifier uniquely refers to the single function object which is created once in the initialisation of the scope.

like image 32
Bergi Avatar answered Oct 16 '22 20:10

Bergi