Skip to content

Instantly share code, notes, and snippets.

@mattacular
Created November 7, 2015 19:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattacular/601fed16a459566bc086 to your computer and use it in GitHub Desktop.
Save mattacular/601fed16a459566bc086 to your computer and use it in GitHub Desktop.
Exercise #1: Closures and IIFE
// by default, variables are assigned to the "window" object (the global namespace)
init = function () {
console.log('Initializing page')
}
if (window.init === init) {
console.log("Yes... they are the same!");
}
// but "init" is a really common function name... we don't want another script to use it
// and accidentally overwrite ours or vice-versa. Closures to the rescue!
(function () {
var init = function () {
console.log("Closure init();")
}
init();
}()); // <-- this is an IIFE
// IIFE look strange at first but let's deconstruct it and you'll see that it actually isn't so scary!
var myFunc = function () {
// ^--starting here
var init = function () {
console.log("Non IIFE Closure init();")
}
init();
}; // <-- and ending here, but remove the semicolon
// remember how I mentioned functions are first-class citizens? Below
// is a standard function call to "myFunc" which we defined above.
// I wrapped it with some unnecessary extra parens which JavaScript
// will ignore in this situation.
(myFunc());
// Now copy from the start to end points defined above in the "myFunc" definition
/*
function () {
// ^--starting here
var init = function () {
console.log("Non IIFE Closure init();")
}
init();
}
*/
// And paste it in to replace the "myFunc" keyword:
(function () {
// ^--starting here
var init = function () {
console.log("IIFE Closure init() #2;")
}
init();
}());
// Voila! Notice that it now looks exactly the same as above.
// But it gets better. This function accepts parameters just like
// any other. However, you are given the opportunity to give the
// reference an alias for use inside your closure. This is handy
// for a variety of situations however it is not necessary. You
// may simply want to use the same variable name for the closure's
// reference to the parameter for the sake of simplicity.
// Quick demo of that:
var valuableData = 'really?';
(function (valuableData) { // <-- and name the closure's internal reference here
console.log(valuableData);
valuableData = "not really imo";
}(valuableData)); // <-- you pass through the "external" reference here
console.log('External "valuableData":', valuableData)
// Be aware that complex types like objects and arrays are passed by value.
// This means changes made to that variable inside of the closure will change
// the external reference as well. This is however not the case with simple
// types like strings as evidenced above. This will be demonstrated in the next
// example.
// Suppose you have a data object with a really long name...
window.myExtremelyLongAndUnweidlyObjectWithImportantData = {
importantProp: "yes",
anotherImportantProp: "also yes",
aFunc: function () {
console.log('myExtremelyLongAndUnweidlyObjectWithImportantData.aFunc() just got called...')
}
};
// And you use it a lot within your code. Inside your closure, you can simple alias it to something
// much more shorter. Again though, because objects are passed through the closure by reference, the
// changes you make to the alias will apply to the external object which is being aliased. Let's see
// this in action...
(function (important) {
important.aFunc(); // its functions and properties are available
// However, if you already a property, it changes everywhere that this object is referenced (such)
// as in the global scope.
console.log('importantProp inside closure before altering', important.importantProp);
// Sometimes this is desirable, sometimes not
important.importantProp = 'no';
}(window.myExtremelyLongAndUnweidlyObjectWithImportantData));
console.log('importantProp back outside of the closure', window.myExtremelyLongAndUnweidlyObjectWithImportantData.importantProp);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment