-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
First set of exercises for events & callbacks #3
Changes from all commits
480fd92
8663cc4
a6acfe7
f67e0d5
12a82f3
e0d56b0
5d00074
ec9b2c9
ff93acd
0685b25
3ced84f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Events and Callbacks | ||
|
||
Working with JavaScript requires an understanding of how | ||
[events](http://glossary.codeunion.io/event) work. Then, to write _evented_ | ||
JavaScript, you need to be familiar with the notion of a | ||
[callback](http://glossary.codeunion.io/callback) function. | ||
|
||
With events, you can write code that says "when this happens, run this | ||
function". For example, a user clicks a button on your web page which makes a | ||
modal window appear. | ||
|
||
In both the browser and in node.js, you can write JavaScript code that _listens | ||
for_ and _responds to_ various events. | ||
|
||
There are three components to writing an event listener in JavaScript: | ||
|
||
1. The event **target** (in node.js, this is called an _emitter_) | ||
2. The **type** (or name) of the event | ||
3. The **callback** function to run when the event happens (or _fires_) | ||
|
||
Here is an example of an event listener that would run in the browser: | ||
|
||
```html | ||
<html> | ||
<body> | ||
<button id="click-me">Press</button> | ||
</body> | ||
|
||
<script type="text/javascript"> | ||
var button = document.getElementById("click-me"); | ||
|
||
button.addEventListener('click', function(evt) { | ||
alert('You clicked me!'); | ||
}); | ||
</script> | ||
</html> | ||
``` | ||
|
||
In the code above, the `button` is the event **target** (the button element that | ||
will fire the event), `'click'` is the event **type** (when the button is | ||
clicked, it fires a this type of event), and the function | ||
|
||
```javascript | ||
function(evt) { | ||
alert('You clicked me!'); | ||
} | ||
``` | ||
|
||
is the **callback** (the code that will run when the event is triggered). | ||
|
||
In node.js, | ||
|
||
## Exercises | ||
|
||
### Level 1 - Functions that Take Functions as Inputs | ||
|
||
* [Passing Functions to Functions](passing_functions_to_functions) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
# Passing Functions to Functions | ||
|
||
## Exercises | ||
|
||
### Functions as inputs? What? | ||
|
||
Can you get functions to return values from inside other functions? | ||
|
||
```javascript | ||
var animalToCatTranslator = function(sentence) { | ||
return sentence.gsub('animal', 'cat'); | ||
} | ||
|
||
var animalToDogTranslator = function(sentence) { | ||
return sentence.gsub('animal', 'dog'); | ||
} | ||
|
||
var favoriteAnimal = function(animalTranslator) { | ||
return animalTranslator("animals are the best!"); | ||
} | ||
|
||
favoriteAnimal(__) | ||
// should evaluate to "cats are the best" | ||
|
||
favoriteAnimal(__) | ||
// should evaluate to "dogs are the best" | ||
``` | ||
|
||
Search suggestion: `pass function as argument to another function javascript` | ||
|
||
> Functions are objects in JavaScript, which means that you can pass them as | ||
> arguments to other functions (just make sure not to include the `()`!). | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd prefer to remove the confounding word |
||
### Functions inside of functions can take their own arguments | ||
|
||
Can you write functions with one parameter and then pass those functions to | ||
_another_ function? | ||
|
||
```javascript | ||
var conservativeSpender = function(balance) { | ||
return balance > 100; | ||
}; | ||
|
||
var liberalSpender = function(balance) { | ||
return balance > 10; | ||
}; | ||
|
||
var shouldIBuyThis = function(balance, spendingStrategy) { | ||
if ( spendingStrategy(balance) ) { | ||
return "Sure! I've got the money!"; | ||
} else { | ||
return "Nope! Gotta keep my savings up!"; | ||
} | ||
} | ||
|
||
shouldIBuyThis(20, __); | ||
// should evaluate to "Nope! Gotta keep my savings up!" | ||
|
||
shouldIBuyThis(20, __); | ||
// should evaluate to "Sure! I've got the money!" | ||
|
||
shouldIBuyThis(__, function(balance) { | ||
return balance > 1000; | ||
}); | ||
// should evaluate to "Nope! Gotta keep my savings up!" | ||
|
||
var horribleSaver = function(balance) { | ||
return balance > 0; | ||
}; | ||
|
||
shouldIBuyThis(__, horribleSaver); | ||
// should evaluate to "Sure! I've got the money!" | ||
|
||
function smarterShouldIBuyThis(cost, balance, strategy) { | ||
var futureBalance = balance - cost; | ||
if ( __(futureBalance) ) { | ||
return "Sure! I've got the money!"; | ||
} else { | ||
return "Nope! Gotta keep my savings up!" | ||
} | ||
} | ||
|
||
smarterShouldIBuyThis(50, 45, horribleSaver); | ||
// should evaluate to "Nope! Gotta keep my savings up!" | ||
``` | ||
|
||
### Calling a function more than once with callbacks | ||
|
||
Can you figure out how the functions below work and solve the missing pieces? | ||
|
||
```javascript | ||
var doItThisManyTimes = function(numberOfTimes, callbackFunction) { | ||
for (var i = 0; i < numberOfTimes; i++) { | ||
callbackFunction(); | ||
} | ||
}; | ||
|
||
doItThisManyTimes(5, __() { | ||
__.__("wow!") | ||
}); | ||
// should print | ||
// wow! | ||
// wow! | ||
// wow! | ||
// wow! | ||
// wow! | ||
|
||
var each = function(array, callbackFunction) { | ||
for (var i = 0; i < array.length; i++) { | ||
callbackFunction(array[i]); | ||
} | ||
} | ||
|
||
each([1,2,3], function(number) { | ||
console.log(__ * 2); | ||
}); | ||
// should print | ||
// 2 | ||
// 4 | ||
// 6 | ||
|
||
var printQs = __(__) { | ||
console.log('Q' * __); | ||
} | ||
|
||
each([1,2,3], printQs); | ||
// should print | ||
// Q | ||
// QQQ | ||
``` | ||
|
||
Search suggestion: `callback function javascript` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This bit looks good. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Though it may be easier for people to get "doThisXTimes" instead of iteration over an array. Maybe that could be a pre-cursor here. |
||
|
||
> When you need to perform the some operation many times within a function, | ||
> using a callback is an effective tool. | ||
|
||
### Use the return value of your callbacks | ||
|
||
Can you figure out how to write callback functions that give values back to | ||
their "caller"? | ||
|
||
```javascript | ||
var map = function(array, callbackFunction) { | ||
var mappedArray = []; | ||
for (var i = 0; i < array.length; i++) { | ||
var item = array[i]; | ||
|
||
mappedArray.push( __(item) ); | ||
} | ||
return __; | ||
} | ||
|
||
map(["one", "two", "three"], __(__) { | ||
__ __.toUpperCase(); | ||
}); | ||
// should evaluate to ["ONE", "TWO", "THREE"] | ||
|
||
var square = function(__) { | ||
__ __ * __; | ||
}; | ||
|
||
map([4, 5, 10], square); | ||
// should evaluate to [16, 25, 100] | ||
``` | ||
|
||
> Pay close attention to the names of functions and their parameters. | ||
|
||
### Doing comparisons in functions is useful for control flow | ||
|
||
Can you figure out how the `filter` function works and write callbacks to filter | ||
out certain elements from arrays? | ||
|
||
```javascript | ||
var filter = function(array, __) { | ||
var filteredArray = []; | ||
for (var i = 0; i < array.length; i++) { | ||
if ( __(array[i]) === true ) { | ||
filteredArray.push(array[i]); | ||
} | ||
} | ||
return filteredArray; | ||
} | ||
|
||
filter([5, -2, 19, -8], function(number) { | ||
return __ __ 0; | ||
}); | ||
// should evaluate to [5, 19] (numbers greater than 0) | ||
|
||
var startsWithA = __(__) { | ||
__ __.charAt(0).toUpperCase() === 'A' | ||
} | ||
|
||
filter(["apple", "aardvark", "zoo", "arch", "goggles"], startsWithA); | ||
// should evaluate to ["apple", "aardvark", "arch"] | ||
``` | ||
|
||
> Conditionals are expressions that return boolean values. Functions can return | ||
> an evaluated expression. Therefore... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would recommend using plain old EventTarget here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what you mean. Link to the EventTarget docs? How does one use a plain EventTarget?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I had forgotten that the browser and node use different classes: http://nodejs.org/api/events.html#events_emitter_addlistener_event_listener
It's probably fine to do a browser example, especially if it includes the HTML/etc. to be fully runnable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also I totally didn't realize that EventTarget is not a pbulic API. My bad.