Telegraph Prep+ Week 4
Anonymous Functions
Closures
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
Who are you?
- Have a mastery of
JS arrays, objects, and loops, functions. - Good understanding of scope, anonymous functions.
- Know what higher order functions, and callbacks are.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
Week 4 will cover
- Anonymous functions (and why they're important.)
- Closures & Closure scope.
- Higher order functions, and buliding libraries.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
Anonymous Functions
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/2215280/anonymous_functions.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
anonymous function
function(item) {
return item * 3;
}
An anonymous function has no name after the 'function' keyword
Often passed as callbacks to higher order functions
(we'll use these often in this class)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
anonymous function
function(item) {
return item * 3;
}
Anonymous functions are important because:
1. They are widely used in the coding community. If you don't know how to approach one you'll be considered a n00b.
2. They allow us to save space in memory by calling a function only when necessary (we'll get to this in a second).
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
anonymous function: Invocation
function(item) {
// 10 is going to take the place of the parameter, item.
return item * 3;
}(10)
// ??
An anonymous function is much more than an 'unnamed' function.
In programming, creating something without assigning it means it's not stored in memory.
If it is not stored in memory, how do we call the function?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
anonymous function: use case
function(item) {
return item * 3;
}()
Calling a function on the exact line doesn't do us much good. Functions are supposed to be recipes that are used over and over again.
Can you think of a way we can replicate that important functionality without naming the function?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
anonymous function & Higher ORder Funcs
// not useful
function(item) {
return item * 3;
}(10);
var multItem = function(item, callback){
return callback(item);
};
// pretty useful
var thirty = multItem(10, function(item){
return item * 3
});
You guessed it! Passing it into a higher order function allows the anonymous function to be called whenever that function is called.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
anonymous function & Higher ORder Funcs
// pretty useful
var thirty = multItem(10, function(item){
return item * 3
});
// VERY useful
var multByAnyNumber = function(item, n){
return multItem(item, function(item){
return item * n
});
};
var twenty = multByAnyNumber(2, 10); // 20
var thirty = multByAnyNumber(5, 6); // 30
An even better use case below, and an intro into what you'll be working toward this week
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
Named vs Anonymous
//Anonymous function saved into a variable
var nameImprover = function (name, adj) {
return 'Col ' + name + ' Mc' + adj + ' pants';
};
//named function
function nameImprover(name, adj) {
return 'Col ' + name + ' Mc' + adj + ' pants';
}
// anonymous function
function (name, adj) {
return 'Col ' + name + ' Mc' + adj + ' pants';
};
// they all work!
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
Key Takeaways
-
ANONYMOUS FUNCTIONS AND NAMED FUNCTIONS WORK *ALMOST* THE SAME WAY - SO DON'T BE AFRAID OF THEM.
-
ANONYMOUS FUNCTIONS CAN ONLY BE INVOKED ON THE LINE THAT THEY ARE CALLED.
-
ONE OF THE BEST USE CASES FOR ANONYMOUS FUNCTIONS ARE WHEN YOU ARE PASSING THEM INTO, OR RETURNING THEM FROM A HIGHER ORDER FUNCTION.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
EXERCISES
-
Repo:
- New Pairs
- References:
https://github.com/TelegraphPrep/week-4-closures
http://slides.com/telegraphprep/telegraphprepweek3-13#/1
scopes, pt 2
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
var firstAlert = function(){
var x = 'Secret Message';
var alerter = function(){
alert(x);
};
alerter();
};
firstAlert();
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
Nested Inner Function
Inner function called within outer function
Let's walk through this code together as though we were the JS interpreter...
var firstAlert = function(){
var x = 'Secret Message';
var alerter = function(){
alert(x);
};
setTimeout(alerter, 1000);
console.log('will still run right after');
};
firstAlert();
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
Nested Inner Function
Inner func called within browser-land
Let's pop this code into the console and see what happens...
var firstAlert = function(){
var x = 'Secret Message';
var alerter = function(){
alert(x);
};
return alerter;
};
var alert1 = firstAlert();
alert1();
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
Returned Inner Function
Inner function called where?
var firstAlert = function(){
var x = 'Secret Message';
var alerter = function(){
alert(x);
};
return alerter;
};
var alert1 = firstAlert();
called outside of outer function
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
var add = function(num){
var num1 = num;
var addToNum1 = function(num2){
return num1 + num2;
};
return addToNum1;
};
var alwaysAdd2 = add(2);
Returned Inner Function
var add = function(num){
var num1 = num;
var addToNum1 = function(num2){
return num1 + num2;
};
return addToNum1;
};
var alwaysAdd2 = add(2);
alwaysAdd2(3); //??
var add = function(num){
var num1 = num;
var addToNum1 = function(num2){
return num1 + num2;
};
return addToNum1;
};
var alwaysAdd2 = add(2);
alwaysAdd2(3); //5
var alwaysAdd10 = add(10);
var add = function(num){
var num1 = num;
var addToNum1 = function(num2){
return num1 + num2;
};
return addToNum1;
};
var alwaysAdd2 = add(2);
alwaysAdd2(3); //5
var alwaysAdd10 = add(10);
alwaysAdd10(3); //??
var add = function(num){
var num1 = num;
var addToNum1 = function(num2){
return num1 + num2;
};
return addToNum1;
};
var alwaysAdd2 = add(2);
alwaysAdd2(3); //5
var alwaysAdd10 = add(10);
alwaysAdd10(3); //13
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
questions?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
Congratulations! You now know closures!
Why are closures important?
- access private variables (ex: module pattern)
- partial application of arguments (currying)*
- recursion involving memoization*
*advanced topics not covered in this class
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
Closure Definition
Closure functions are declared inside outer functions (nested) and invoked in a context outside of the one they were created in.
They retain access to a closure variable from the context the function was created in.
Remember a closure consists of
TWO key components:
- closure function
- closure variable
Recipe: creation
1. Create your parent function.
2. Define some variables in the parent's local scope.
(they can be accessed by the child function)
3. Define a function inside the parent function.
(aka defining a "child" function or "nested" function)
4. Return that child function from inside the parent.
function outerFunc() { var parentVar = "local to parent"; function innerFunc() { return parentVar + ' but accessed by child!'; }; return innerFunc; }
1. 2. 3. 4.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
closure variable
closure function
RECIPE: Execution
function outerFunc() {
var parentVar = "local to parent";
function innerFunc() {
return parentVar + ' but accessed by child!';
};
return innerFunc;
}
// STEP 1 - Invoke the parent function.
var example = outerFunc();
console.log(example);
// We see example now stores the child function.
// STEP 2 - Invoke the child function.
var result = example();
console.log(result);
// What's the end result?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
Closure Definition, revisited
Closure functions are declared inside outer functions (nested) and invoked in a context outside of the one they were created in.
A: outside of scope it was created in
Q: where is closureFunc getting invoked?
var firstAlert = function(){
var x = 'Secret Message';
var alerter = function(){
alert(x);
};
alerter();
};
firstAlert();
var firstAlert = function(){
var x = 'Secret Message';
var alerter = function(){
alert(x);
};
return alerter;
};
firstAlert();
var firstAlert = function(){
var x = 'Secret Message';
var alerter = function(){
alert(x);
};
return alerter;
};
firstAlert()();
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
Closure Definition, revisited
Closure functions retain access to closure variables from the context the function was created in.
var firstAlert = function(){
var x = 'Secret Message';
var alerter = function(){
alert(x);
};
return alerter;
};
var myAlert = firstAlert();
// myAlert still has access to x
Gotcha!?
var sayAlice = function(){
var makeLog = function() {
console.log(alice);
};
var alice = 'Why hello there, Alice!';
return makeLog;
};
var log = sayAlice();
log(); //??
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
What will we see in the console?
Walk through the code as the JS interpreter would
Scope is created at runtime
var makeStopwatch = function(){
var elapsed = 0;
var increase = function(){ elapsed++; };
setInterval(increase, 1000);
var stopwatch = {
getTime: function() { return elapsed; }
};
return stopwatch;
};
var watch1 = makeStopwatch();
// wait 3 seconds...
var watch2 = makeStopwatch();
watch1.getTime() - watch2.getTime(); //??
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
how many "elapsed" variables are created?
everytime makeStopwatch is invoked, a new closure comes into existence
key takeaways
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
Closures functions are nested inside outer functions and retain access to closure variables in the context the function was created in
function outerFunc() {
var closureVar = "Only the closureFunc can access me!";
function closureFunc() {
console.log('closureVar says:', closureVar);
}
return closureFunc;
};
var innerFunc = outerFunc();
innerFunc(); // this is the closure function
// --> "closureVar says: Only the closureFunc can access me!"
Questions
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
Exercise Time!
Repo:
Same Pairs
Slides:
https://github.com/TelegraphPrep/week-4-closures
![](https://s3.amazonaws.com/media-p.slid.es/uploads/362520/images/1635394/stucked.png)
http://slides.com/telegraphprep/telegraphprepweek3-13#/2
Anonymous Functions Review & Closures
By telegraphprep
Anonymous Functions Review & Closures
An introduction to functional programming
- 827