Some definitions:
- A JS function expression: var myCode = function(a, b) {stuff;};
- A JS function declaration: function myCode (a, b) {stuff;};
- Hoisting: Pretty much what it sounds like, some things are lifted upwards and therefore are executed sooner in the script than where they were originally written. So, something that was written like so:
function bunny (){
rabbit();
var carrot= 2;
}
Is actually executed like so:
function bunny (){
var carrot; //declaration gets hoisted
rabbit();
carrot= 2; //assignment stays put
}
In JS, a name enters a scope in in one of four ways:
Function declarations and variable declarations are always moved (“hoisted”) invisibly to the top of their containing scope by the JavaScript interpreter. Function parameters and language-defined names are, obviously, already there. [names are also resolved in this order] [emphasis mine]
- Language-defined: All scopes are, by default, given the names
this
andarguments
.- Formal parameters: Functions can have named formal parameters, which are scoped to the body of that function.
- Function declarations: These are of the form function foo() {}.
- Variable declarations: These take the form var foo;.
When to use what: If you're aware of hoisting and how things will execute, then use whatever floats your boat, even intentionally use hoisting to get your function declaration moved up. Because a function declaration is all declaration, not declaration plus assignment as in a function expression, the entire function gets hoisted at once. A function expression only has the "var blah;" hoisted, leaving the actual function body (assignment expression) behind. (see also Angus Croll on function declarations/expressions. The fifth time I came back to that page I got the right quiz answers (and not just from memorizing them)).
How functions execute with hoisting when a script runs (examples taken from my hangout on air with JBeach):
Written like so:
(function () {
a = grapefruit;
b = applesauce;
function grapefruit () { //function declaration
return 'citrus in your eye';
};
var applesauce = function () { //function expression
return 'goodness';
};
}());
Executed like so:
(function () {
function grapefruit () { //function declaration hoisted
return 'citrus in your eye';
};
var applesauce; //function expression declaration (?) hoisted
a = grapefruit;
b = applesauce;
applesauce = function () { //function expression
return 'goodness';
};
}()); // returns "citrus in your eye" for a and "undefined" for b.
I think I've got the concept, even if I haven't quite got the details of how it runs (slight lack of applied JS knowledge here, but working on that).
There was also mention of NFEs and IIFEs somewhere along the way here. NFEs are nicer than anonymous functions should you need to track one through a tangle of code. IIFEs are somewhat also known as Self-Executing Anonymous Functions, but with some nuance. An IIFE does invoke itself, can be anonymous or named, and can be self-executing.
- Named Function Expression (NFE):
var myFunc = function myFunc (){code here}
- Immediately Invoked Function Expression (IIFE):
(function myFunc (){code here}());
Disclaimer: For goodness' sake don't take my word for any/all of this if you've just stumbled across my blog. I'm just learning and these posts are essentially my notes. Please do read the articles I've linked to, read as much as you can, experiment, and figure it all out for yourself, too.
And if I've got something not quite right or downright wrong, please leave a comment. Thank you...
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.