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?
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With