DAY 1
FUNCTIONAL
PROGRAMMING
Strengthen your understanding
of tricky JavaScript concepts by:
Understanding how to use functional utility methods
Understanding how to implement functional methods
Applying JS fundamentals throughout the process
This course is not about mastering functional programming
But it will prepare you well if you decide to take the next step in that journey and most importantly, it will make you a more confident and capable JavaScript programmer.
Some tips on success
Sincere, not serious
This is an interactive course!
Expect to have to think critically and answer questions either live or just in your head.
There will be uncomfortable moments.
It's a game!
OBJECTS & ARRAYS
Overview
@BIANCAGANDO
FEM 2017
1. Property Access
2. Bracket Notation
3. Dot Notation
4. Dot vs Bracket
5. Nested Objects
6. Object Literals
7. Iteration
Data
@BIANCAGANDO
FEM 2017
var box = {};
@BIANCAGANDO
FEM 2017
var box = {};
box.material = "cardboard";
var box =
{"material" : "cardboard"}
@BIANCAGANDO
FEM 2017
var box = {};
box.material = "cardboard";
box.material; //??
var box =
{"material" : "cardboard"}
@BIANCAGANDO
FEM 2017
var box = {};
box.material = "cardboard";
var cb = box.material;
var box =
{"material" : "cardboard"}
@BIANCAGANDO
FEM 2017
var box = {};
box.material = "cardboard";
var cb = box.material;
cb; //??
box.material = "titanium";
cb; //??
box =
{"material" : "cardboard"}
cb = "cardboard"
box =
{"material" : "titanium"}
@BIANCAGANDO
FEM 2017
var box = {};
box.material = "cardboard";
box.material; //"cardboard"
box.size; //??
var box =
{"material" : "cardboard"}
@BIANCAGANDO
FEM 2017
var box = {};
box["material"] = "cardboard";
box.material; //??
var box =
{"material" : "cardboard"}
@BIANCAGANDO
FEM 2017
var box = {};
box["material"] = "cardboard";
box.material; //??
var box =
{"material" : "cardboard"}
@BIANCAGANDO
FEM 2017
var box = {};
box["material"] = "cardboard";
box.material; //??
var box =
{"material" : "cardboard"}
@BIANCAGANDO
FEM 2017
var box = {};
box["material"] = "cardboard";
var key = "material";
box[key]; //??
@BIANCAGANDO
FEM 2017
var box = {};
box["material"] = "cardboard";
var func = function(){
return "material";
};
box[func()]; //??
@BIANCAGANDO
FEM 2017
var box = {};
box['material'] = "cardboard";
var key = 'material';
box['key']; //undefined
box.key; //undefined
box[key]; //"cardboard"
@BIANCAGANDO
FEM 2017
var box = {};
box['material'] = "cardboard";
box[0] = 'meow';
box['^&*'] = "testing 123";
var test = box['^&*'];
box =
{"material" : "cardboard",
"0" : "meow",
"^&*" : "testing 123"
}
@BIANCAGANDO
FEM 2017
@BIANCAGANDO
FEM 2017
var box = {};
box["material"] = "cardboard";
box["size"] = {
"height": 2,
"width": 80
};
box.area = function(){
return box.size.height * box.size.width;
};
@BIANCAGANDO
FEM 2017
@BIANCAGANDO
FEM 2017
@BIANCAGANDO
FEM 2017
var box = {};
box['material'] = "cardboard";
box[0] = 'meow';
box['^&*'] = "testing 123";
for(var key in box){
console.log(key); //??
}
@BIANCAGANDO
FEM 2017
var box = {};
box['material'] = "cardboard";
box[0] = 'meow';
box['^&*'] = "testing 123";
for(var key in box){
console.log(key); //??
}
@BIANCAGANDO
FEM 2017
var box = {};
box['material'] = "cardboard";
box[0] = 'meow';
box['^&*'] = "testing 123";
for(var key in box){
console.log(box[key]); //??
}
@BIANCAGANDO
FEM 2017
What is an object?
What is the difference between dot and bracket notation?
How do you add a property with a key that contains special characters?
How do you add a property whose key and value are stored in different variables?
How do we loop through objects to access the values?
@BIANCAGANDO
FEM 2017
When can you only use dot notation and not bracket?
When can you only use brackets and not dot?
How do you add a property with a key that is stored in a variable?
How do you access an object that is inside another object?
How do you create an object that is nested inside another object?
ARRAYS
Arrays vs Objects
Overview
Arrays vs Objects
Access && Assignment
Native Methods & Properties
Iteration
Access & Assignment
var box = [];
box[0] = true;
box[1] = 'meow';
box.push({'hello' : 'goodbye'});
var i = 0;
box[i]; // ??
box[1];
box.pop() //??
[true, 'meow', {'hello' : 'goodbye'}]
index# 0 1 2
{0 : 'meow', 'size' : 9 }
Access & Assignment
var
box = [];
box['size'] = 9;
box['0'] = 'meow';
box['size'];
// ??
box[0];
// ??
[true, 'meow', {'hello' : 'goodbye'}]
index# 0 1 2
{0 : 'meow', 'size' : 9 }
Access & Assignment
var box = [];
box['size'] = 9;
box['0'] = 'meow';
box.size; // ??
box[0]; // ??
['meow']
index # 0
{0 : 'meow', 'size' : 9 }
Access & Assignment
var box = [];
box['size'] = 9;
box['0'] = 'meow';
box.size; // ??
box.0; // ??
['meow']
index # 0
{0 : 'meow', 'size' : 9 }
Iteration
var box = [];
box['size'] = 9;
box['0'] = 'meow';
for(var k in box){
console.log(k); // ??
}
['meow']
index # 0
{0 : 'meow', 'size' : 9 }
Iteration
var box = [];
box['size'] = 9;
box['0'] = 'meow';
for(var k in box){
console.log(k); // ??
}
['meow']
index # 0
{0 : 'meow', 'size' : 9 }
Iteration
var box = [];
box['size'] = 9;
box['0'] = 'meow';
box.push('Whoohoo!');
for(var k in box){
console.log(box[k]);
}
for(var i = 0; i < box.length; i++){
console.log(i); //??
}
['meow']
index # 0
{0 : 'meow', 'size' : 9 }
_.each() / forEach DEFINED
_.each(
['observatory','ballroom', 'library'],
function(value, index, list){ ... }
);
['observatory','ballroom','library']
.forEach(function(value, index, list){...});
Iterates over a list of elements, passing the values to a function.
Each invocation of iterator, the function, is called with three arguments: (element, index, list). If list is a JavaScript object, iterator's arguments will be (value, key, list).
_.each() usage
var rooms = ['observatory','ballroom', 'library'];
var logger = function(val){
console.log(val);
};
_.each(rooms, logger);
//_.each(list,iterator)
_.each() usage
var rooms = ['observatory','ballroom', 'library'];
//_.each(list,iterator)
_.each() usage
var rooms = ['observatory','ballroom', 'library'];
var logger = function(val){
console.log(val);
};
//_.each(list,iterator)
_.each() usage
var rooms = ['observatory','ballroom', 'library'];
var logger = function(val){
console.log(val);
};
//_.each(list,iterator)
_.each() usage
var rooms = ['observatory','ballroom', 'library'];
var logger = function(val){
console.log(val);
};
//_.each(list,iterator)
Exercise
Complete the rest of this function so that it works as described in the previous slides:
_.each = function(list, callback) {
//... TODO
}
NESTING
var box = {};
box['innerBox'] = {};
var box =
{"innerBox" : {}}
ACCESS & ASSIGNMENTS
let suspects = [];
suspects[0] = 'scarlet';
suspects[1] = 'mustard';
suspects.push({'green' : true});
var i = 0;
suspects[i]; // ??
suspects[1];
suspects.pop() //??
[scarlet, 'mustard', {'green' : true}]
index# 0 1 2
NESTING
var box = {};
box['innerBox'] = {};
box['innerBox']['full'] = true;
var box =
{"innerBox" : {
full: true
}
}
NESTING
var box = {};
box['innerBox'] = {};
box['innerBox']['full'] = true;
var box =
{"innerBox" : {
full: true
}
}
NESTING
var box = {};
box.innerBox = {};
box.innerBox.full = true;
box.innerBox; //??
var box =
{"innerBox" : {
full: true
}
}
NESTING
var box = {};
box.innerBox = {};
box.innerBox.full = true;
var myInnerBox = box.innerBox;
myInnerBox; //??
var box =
{"innerBox" : {
full: true
}
}
NESTING
var box = {};
box.innerBox = {};
box.innerBox.babyBox = {};
box.innerBox['babyBox']; //??
box.innerBox['babyBox'].says = "What's up!?";
var box =
{"innerBox" : {
babyBox : {
says:
"What's up!?"
}
}
NESTING
var box = {};
box['innerBox'] = {};
box['innerBox'].full = true;
box[innerBox]['height'] = 10;
box[innerBox2].full = false;
SPREAD / REST
var box = {};
box['innerBox'] = {};
box['innerBox'].full = true;
box[innerBox]['height'] = 10;
box[innerBox2].full = false;
1. What are some different methods of adding values to an array?
2. What do you use to loop through an array?
3. What do you use to loop through an array?
4. What are some special properties about arrays that are different from objects?
5. What are some ways to access values in your array?
LIST TRANSFORMATIONS
function CreateSuspectObjects(name) {
return {
name: name,
color: name.split(' ')[2],
speak: function () {
console.log("my name is ", name);
}
};
};
var suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White'];
LIST TRANSFORMATIONS
function CreateSuspectObjects(name) {
return {
name: name,
color: name.split(' ')[1],
speak() {
console.log("my name is ", name);
}
};
};
var suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White'];
LIST TRANSFORMATIONS
function CreateSuspectObjects(name) {
return {
name: name,
color: name.split(' ')[1],
speak() {
console.log("my name is ", name);
}
};
};
var suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White', ...];
var suspectsList = [];
LIST TRANSFORMATIONS
function CreateSuspectObjects(name) {
return {
name: name,
color: name.split(' ')[1],
speak() {
console.log("my name is ", name);
}
};
};
var suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White'];
var suspectsList = [];
for(var i = 0; i < suspects.length; i++){
suspect = CreateSuspectObjects(suspects[i]) suspectsList.push(suspect);
}
LIST TRANSFORMATIONS
function CreateSuspectObjects(name) {
return {
name: name,
color: name.split(' ')[1],
speak() {
console.log("my name is ", name);
}
};
};
var suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White'];
var suspectsList = [];
for(var i = 0; i < suspects.length; i++){
suspectsList.push(CreateSuspectObjects(suspects[i]));
}
FOR - OF LOOP
function CreateSuspectObjects(name) {
return {
name: name,
color: name.split(' ')[1],
speak() {
console.log("my name is ", name);
}
};
};
var suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White'];
var suspectsList = [];
for(var i = 0; i < suspects.length; i++){
suspectsList.push(CreateSuspectObjects(suspects[i]));
}
LOOPING WITH_.each
function CreateSuspectObjects(name) {
return {
name: name,
color: name.split(' ')[1],
speak() {log("my name is ${name}");}
};
};
var suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White'];
var suspectsList = [];
for(var i = 0; i < suspects.length; i++){
suspectsList.push(CreateSuspectObject(suspects[i]));
}
LOOPING WITH_.each
function CreateSuspectObjects(name) {
return {
name: name,
color: name.split(' ')[1],
speak() {log("my name is ${name}");}
};
};
var suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White'];
var suspectsList = [];
_.each(suspects, function(name) {
suspectsList.push(CreateSuspectObjects(name));
});
_.map() DEFINED
_.map([1,2,3], function(v,i,list){console.log(v)})
Produces a new array of values by mapping each value in list through a transformation function ( iterator).
_.map() USAGE
var pocketmon = ['Charisaur', 'Bulbazard', 'Twomew'];
//_.map(list, iterator)
_.map() USAGE
var pocketmon = ['Charisaur', 'Bulbazard', 'Twomew'];
var excitedArr = function(val){
return val + '!!!';
};
//_.map(list, iterator)
_.map vs _.each
function AnimalMaker(name) {
return {
speak: function () {
console.log("my name is ", name);
}
};
};
var animalNames = ['', '', ''];
var farm = _.map(animalNames, function (name) {
return AnimalMaker(name);
});
_.each(farm, function (animal) {
animal.speak();
});
Looping with_.map
function AnimalMaker(name) {
return {
speak: function () {
console.log("my name is ", name);
}
};
};
var animalNames = ['', '', ''];
var farm = []
_.each(animalNames, function (name) {
farm.push(AnimalMaker(name));
});
Looping with_.map
function AnimalMaker(name) {
return {
speak: function () {
console.log("my name is ", name);
}
};
};
var animalNames = ['', '', ''];
var farm = _.map(animalNames, function (name) {
return AnimalMaker(name);
});
FUNCTIONS
ANATOMY
@BIANCAGANDO
FEM 2017
DEFINITION
@BIANCAGANDO
FEM 2017
var nameImprover = function (name, adj) {
return 'Col ' + name + ' Mc' + adj + ' pants';
};
$('body').hide();
myArr.forEach(function(val){ console.log(val);});
$('button').on('click', function(){
console.log('Don\'t press my buttons!');
});
NAME
@BIANCAGANDO
FEM 2017
var nameImprover = function (name, adj) {
return 'Col ' + name + ' Mc' + adj + ' pants';
};
$('body').hide();
myArr.forEach(function(val){ console.log(val);});
$('button').on('click', function(){
console.log('Don\'t press my buttons!');
});
BODY
@BIANCAGANDO
FEM 2017
var nameImprover = function (name, adj) {
return 'Col ' + name + ' Mc' + adj + ' pants';
};
$('body').hide();
myArr.forEach(function(val){ console.log(val);});
$('button').on('click', function(){
console.log('Don\'t press my buttons!');
});
INVOCATION / CALL-TIME
@BIANCAGANDO
FEM 2017
var nameImprover = function (name, adj) {
return 'Col ' + name + ' Mc' + adj + ' pants';
};
$('body').hide();
myArr.forEach(function(val){ console.log(val);});
$('button').on('click', function(){
console.log('Don\'t press my buttons!');
});
ARGUMENTS / PARAMETERS
@BIANCAGANDO
FEM 2017
var nameImprover = function (name, adj) {
return 'Col ' + name + ' Mc' + adj + ' pants';
};
$('body').hide();
myArr.forEach(function(val){ console.log(val);});
$('button').on('click', function(){
console.log('Don\'t press my buttons!');
});
RETURN / SIDE EFFECTS
@BIANCAGANDO
FEM 2017
var nameImprover = function (name, adj) {
return 'Col ' + name + ' Mc' + adj + ' pants';
};
$('body').hide();
myArr.forEach(function(val){ console.log(val);});
$('button').on('click', function(){
console.log('Don\'t press my buttons!');
});
RETURN / SIDE EFFECTS
@BIANCAGANDO
FEM 2017
var nameImprover = (name, adj) => {
return 'Col ${name} Mc ${adj} pants';
};
$('body').hide();
myArr.forEach(val => console.log(val));
$('button').on('click', () => {
console.log('Don\'t press my buttons!');
});
QUICK REVIEW
@BIANCAGANDO
FEM 2017
var add = function(a, b){
return a + b;
};
add(3, 4, 5); // ??
add(4, 10, 3); //13?
ARGUMENTS KEYWORD
@BIANCAGANDO
FEM 2017
var add = function(a, b){
console.log(arguments); //logs [3,10,5]
return a + b;
};
add(3, 10, 5); //13
ARGUMENTS KEYWORD
@BIANCAGANDO
FEM 2017
var add = function(a, b){
console.log(arguments); //logs [3,10,5]
return a + b;
};
add(3, 10, 5); //18??
DEFAULT PARAMETERS
@BIANCAGANDO
FEM 2017
var add = function(a, b){
console.log(arguments); //logs [3,10,5]
return a + b;
};
add(3, 10, 5); //18??
SPREAD / REST
@BIANCAGANDO
FEM 2017
var add = function(a, b){
arguments.slice(0,1) //ERROR!!
return a + b;
};
add(3, 10, 5);
ARRAY-LIKE OBJECT
@BIANCAGANDO
FEM 2017
var add = function(a, b){
Array.prototype.slice.call(arguments)
return a + b;
};
add(3, 10, 5);
CHAINING
@BIANCAGANDO
FEM 2017
const x = 'y'
function name() {
console.log('hello there')
}
P.S. FUNCTIONS ARE OBJECTS!
@BIANCAGANDO
FEM 2017
var add = function(a, b){
return a + b;
};
add.example = 'testing 123!';
@BIANCAGANDO
FEM 2017
SCOPE
@BIANCAGANDO
FEM 2017
OVERVIEW
@BIANCAGANDO
FEM 2017
LOCAL SCOPE
var func = function(){
var local = true;
};
console.log(local);
@BIANCAGANDO
FEM 2017
GLOBAL SCOPE
var x = 'global!';
//inside a function
function encapsulate(){
z = 'global here, too!';
window.y = 'also global!';
}
@BIANCAGANDO
FEM 2017
PARENT vs CHILD SCOPE
var g = 'global';
function blender(fruit) {
var b = fruit;
var y = 'yogurt';
function bs() {
alert( b + ' and ' + y + ' makes ' + b + ' swirl');
}
bs();
}
blender('blueberry');
@BIANCAGANDO
FEM 2017
PRIVACY
var g = 'global';
function blender(fruit) {
var b = fruit;
var y = 'yogurt';
function bs() {
alert( b + ' and ' + y + ' makes ' + b + ' swirl');
}
bs();
}
blender('blueberry');
@BIANCAGANDO
FEM 2017
CREATING SCOPES
@BIANCAGANDO
FEM 2017
PRECEDENCE
var g = "global";
function go() {
var l = "local";
var g = "in here!";
alert(g + " inside go");
}
go();
alert(g + " outside go");
@BIANCAGANDO
FEM 2017
BLOCK SCOPE
var inBlock = false;
for(var i = 0; i < 5; i++){
var inBlock = true;
};
if(inBlock){
console.log('Is there block scope? ' + !inBlock);
}
@BIANCAGANDO
FEM 2017
BLOCK SCOPE
var inBlock = false;
for(var i = 0; i < 5; i++){
var inBlock = true;
};
if(inBlock){
console.log('Is there block scope? ' + !inBlock);
}
@BIANCAGANDO
FEM 2017
HIGHER-ORDER FUNCTIONS AND CALLBACKS
@BIANCAGANDO
FEM 2017
HIGHER-ORDER FUNCTIONS
element.addEventListener("click", function(){
console.log("element clicked!");
});
1. Takes a function as an input (argument)
@BIANCAGANDO
FEM 2017
HIGHER-ORDER FUNCTIONS
var add = function(num){
var num1 = num;
return addToNum1 = function(num2){
return num1 + num2;
};
};
2. Returns a function as the output
@BIANCAGANDO
FEM 2017
CALLBACKS
var ifElse = function(condition, isTrue, isFalse){
if(condition){
isTrue;
} else {
isFalse;
}
};
ifElse(true,
function(){ console.log(true);},
function(){ console.log(false);}
);
@BIANCAGANDO
FEM 2017
CALLBACKS
var ifElse = function(condition, isTrue, isFalse){
if(condition){
isTrue();
} else {
isFalse();
}
};
var logTrue = function(){ console.log(true); };
var logFalse = function(){ console.log(false); };
ifElse(true,logTrue,logFalse);
@BIANCAGANDO
FEM 2017
PASSING ARGUMENTS
var increment = function(n){ return n + 1; };
var square = function(n){ return n*n; };
var doMathSoIDontHaveTo = function(n, func){ return func(n); };
doMathSoIDontHaveTo(5, square);
doMathSoIDontHaveTo(4, increment);
@BIANCAGANDO
FEM 2017
PASSING ARGUMENTS
var ifElse = function(condition, isTrue, isFalse){
if(condition){
isTrue();
} else {
isFalse();
}
};
@BIANCAGANDO
FEM 2017
PASSING ARGUMENTS
var ifElse = function(condition, isTrue, isFalse, arg){
if(condition){
isTrue(arg);
} else {
isFalse(arg);
}
};
@BIANCAGANDO
FEM 2017
[xtra credit]
PASSING ARGUMENTS
var ifElse = function(condition, isTrue, isFalse){
if(condition){
isTrue.apply(this, [].slice.call(arguments,3));
} else {
isFalse.apply(this, [].slice.call(arguments,3));
}
};
@BIANCAGANDO
FEM 2017
FUNCTIONAL UTILITIES
@BIANCAGANDO
FEM 2017
CLOSURE
@BIANCAGANDO
FEM 2017
CLOSURE EXAMPLE
var closureAlert = function(){
var x = "Help! I'm a variable stuck in a closure!";
var alerter = function(){
alert(x);
};
alerter();
};
@BIANCAGANDO
FEM 2017
CLOSURE EXAMPLE
var closureAlert = function(){
var x = "Help! I'm a variable stuck in a closure!";
var alerter = function(){
alert(x);
};
setTimeout(alerter, 1000);
console.log('will still run right after');
};
@BIANCAGANDO
FEM 2017
CLOSURE EXAMPLE
var closureAlert = function(){
var x = 0;
var alerter = function(){
alert(++x);
};
return alerter;
};
var funcStorer = closureAlert();
var funcStorer2 = closureAlert();
funcStorer();
@BIANCAGANDO
FEM 2017
CLOSURE EXAMPLE
var add = function(num){
var num1 = num;
var addToNum1 = function(num2){
return num1 + num2;
};
return addToNum1;
};
@BIANCAGANDO
FEM 2017
CLOSURE EXAMPLE
function counter() {
var n = 0;
return {
count: function() { return ++n; },
reset: function() { n = 0; }
};
};
@BIANCAGANDO
FEM 2017
CLOSURE EXAMPLE
function counter() {
var n = 0;
return {
count: function() { return n++; },
reset: function() { n = 0; }
};
};
var c = counter(), d = counter(); c.count();
d.count();
c.reset();
c.count();
d.count();
@BIANCAGANDO
FEM 2017
RECIPE
@BIANCAGANDO
FEM 2017
EXECUTION
Text
@BIANCAGANDO
FEM 2017
GOTCHA!
var sayAlice = function(){
var makeLog = function() {
console.log(alice);
};
var alice = 'Why hello there, Alice!';
return makeLog;
};
@BIANCAGANDO
FEM 2017
var makeStopwatch = function(){
console.log('initialized');
var elapsed = 0;
console.log(elapsed);
var stopwatch = function(){
console.log('stopwatch');
return elapsed;
};
var increase = function(){ elapsed++; };
setInterval(increase, 1000);
return stopwatch;
};
var x = makeStopwatch();
@BIANCAGANDO
FEM 2017
MODULE PATTERN
var Module = function(){
var privateProperty = 'foo';
function privateMethod(args){
// do something
};
return {
publicProperty: "",
publicMethod: function(args){
// do something
},
privilegedMethod: function(args){
privateMethod(args);
}
};
};
@BIANCAGANDO
FEM 2017
MODULE PATTERN
var Car = function(){
var gasolineLevel = 10;
function useGas(amt){
if(gasolineLevel - amt < 0){
console.log("out of gas :[");
} else {
gasolineLevel -= amt;
}
};
return {
radioStation: "104.5",
changeStation: function(station){
this.radioStation = station;
},
go: function(speed){ useGas(speed); }
};
};
@BIANCAGANDO
FEM 2017
ASYNC PATTERNS