JavaScript Fundamentals
I'm Bianca
- Open source JavaScript framework developer, consultant, and trainer @Bitovi.
- @BiancaGando
- I like really bad puns, board games, riddles, and mysteries...
@BIANCAGANDO
FEM 2017
This course is not about 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.
@BIANCAGANDO
FEM 2017
This course is about figuring out what happened to
Mr. Boddy
... what?
@BIANCAGANDO
FEM 2017
Strengthen your understanding
of tricky JavaScript concepts by:
Understanding how to use functional utility methods
Understanding how to implement those methods
Applying JS fundamentals throughout the process
Adding some related ES6 features
@BIANCAGANDO
FEM 2017
Expectations
Sincere, not serious.
This is an interactive course.
There will be uncomfortable moments!
Expect to have to think critically, answer questions, ask a questions.
@BIANCAGANDO
FEM 2017
Note: The first example of a concept tends to have intentional mistakes in them that are corrected in later slides.
Some tips on success
@BIANCAGANDO
FEM 2017
What is Functional Programming?
@BIANCAGANDO
FEM 2017
OBJECTS & ARRAYS
Overview
@BIANCAGANDO
FEM 2017
1. Property Access
2. Dot vs Bracket
3. Destructuring
4. Nesting + Loops
5. Nesting + Destructuring
Data
@BIANCAGANDO
FEM 2017
var person = {};
@BIANCAGANDO
FEM 2017
var person = {};
person.name = "Mrs. White";
var person = {
"name" : "Mrs. White"
};
@BIANCAGANDO
FEM 2017
var person = {};
person.name = "Mrs. White";
person.name; //??
var person = {
"name" : "Mrs. White"
};
@BIANCAGANDO
FEM 2017
var person = {};
person.name = "Mrs. White";
var who = person.name;
var person =
{"name" : "Mrs. White"}
who
"Mrs. White"
var person = {
"name" : "Mrs. White"
};
@BIANCAGANDO
FEM 2017
var person = {};
person.name = "Mrs. White";
var who = person.name;
who; //??
person.name = "Mr. White";
who; //??
who
"Mrs. White"
@BIANCAGANDO
FEM 2017
var person = {};
person.name = "Mrs. White";
var who = person.name;
who; //??
person.name = "Mr. White";
who; //??
who
"Mrs. White"
person
"name" :
"Mrs. White"
@BIANCAGANDO
FEM 2017
var person = {};
person.name = "Mrs. White";
var who = person.name;
who; //??
person.name = "Mr. White";
who; //??
who
"Mrs. White"
person
"name" :
"Mrs. White"
"Mr. White"
@BIANCAGANDO
FEM 2017
var person = {};
person.name = "Mrs. White";
var who = person.name;
person.name = "Mr. White";
who.story; //??
who
"Mrs. White"
person
"name" :
"Mrs. White"
"Mr. White"
@BIANCAGANDO
FEM 2017
var person = {};
person.name = "Mrs. White";
var who = person.name;
person.name = "Mr. White";
who.story; //??
who
"Mrs. White"
person
"name" :
"Mrs. White"
"Mr. White"
My wife is an array of sunshine!
@BIANCAGANDO
FEM 2017
var person = [];
person.name = "Mrs. White";
var who = person.name;
who; //??
who
??
person
"name" :
"Mrs. White"
@BIANCAGANDO
FEM 2017
var person = [];
person.name = "Mrs. White";
var who = person.name;
who; //??
who
"Mrs. White"
person
"name" :
"Mrs. White"
@BIANCAGANDO
FEM 2017
var person = [];
person.name = "Mrs. White";
var who = person.name;
who;
typeof white === "array"; //??
who
"Mrs. White"
person
"name" :
"Mrs. White"
@BIANCAGANDO
FEM 2017
var person = [];
person.name = "Mrs. White";
var who = person.name;
person[0] = "I was not in
the Billiards room";
who
"Mrs. White"
person
"name" :
"Mrs. White"
@BIANCAGANDO
FEM 2017
var person = [];
person.name = "Mrs. White";
var who = person.name;
person[0] = "I was not in
the Billiards room";
who
"Mrs. White"
person
"name" :
"Mrs. White"
"0" :
"I was not in... "
@BIANCAGANDO
FEM 2017
var person = [];
person.name = "Mrs. White";
person[plea] = "I would never!"
who
"Mrs. White"
person
"name" :
"Mrs. White"
"I would never!"
@BIANCAGANDO
FEM 2017
var person = [];
var plea = "wouldShe"
person.name = "Mrs. White";
person[plea] = "I would never!"
who
"Mrs. White"
person
"name" :
"wouldShe":
"Mrs. White"
"I would never!"
@BIANCAGANDO
FEM 2017
var person = [];
var plea = "wouldShe"
person.name = "Mrs. White";
person[plea] = "I would never!"
person.plea //??
who
"Mrs. White"
person
"name" :
"wouldShe":
"Mrs. White"
"I would never!"
@BIANCAGANDO
FEM 2017
var person = [];
var plea = "wouldShe"
person.name = "Mrs. White";
person["plea"] = "I would never!"
person.plea //??
who
"Mrs. White"
person
"name" :
"plea":
"Mrs. White"
"I would never!"
@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
Create an object using bracket and dot notation that represents the characters and related data you may find in a game of Clue.
@BIANCAGANDO
FEM 2017
@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?
@BIANCAGANDO
FEM 2017
@BIANCAGANDO
FEM 2017
Variable declarations: const [first, second] = [true, false];
let [first, second] = [true, false];
var [first, second] = [true, false]; Assignment:
[first, second] = [true, false];
@BIANCAGANDO
FEM 2017
THE SOURCE
THE TARGET
@BIANCAGANDO
FEM 2017
Variable declarations: const {first, second} = {first: 0 , second: 1}
let {first, second} = {first: 0 , second: 1}
var {first, second} = {first: 0 , second: 1}
Assignment:
{first, second} = {first: 0 , second: 1}
@BIANCAGANDO
FEM 2017
THE SOURCE
THE TARGET
@BIANCAGANDO
FEM 2017
1. Create an object that looks like this:
{"name": "Rusty", "room":"kitchen", "weapon":"candlestick"}
2. Extract out the weapon and location using destructuring
List
Transforms
NESTING
const game = {};
game['suspects'] = [];
const game = {
'suspects': []
}
@BIANCAGANDO
FEM 2017
NESTING
const game = {};
game['suspects'] = [];
game.suspects.push({
name:"Rusty",
color: "orange"
})
@BIANCAGANDO
FEM 2017
const game = {
'suspects': [
{
name: "Rusty",
color: "orange"
}
]
}
NESTING
const game = {};
game['suspects'] = [];
game.suspects.push({
name:"Rusty",
color: "orange"
});
game.suspects[1] = {
name: "Miss Scarlet",
color: "red"
};
@BIANCAGANDO
FEM 2017
const game = {
'suspects': [
{
name: "Rusty",
color: "orange"
},
{
name: "Miss Scarlet",
color: "red"
}
]
}
NESTING
const game = {
'suspects': [
{
name: "Rusty",
color: "orange"
}, {
name: "Miss Scarlet",
color: "red"
}
]
}
game["suspects"] //??
@BIANCAGANDO
FEM 2017
NESTING
const game = {
'suspects': [
{
name: "Rusty",
color: "orange"
}, {
name: "Miss Scarlet",
color: "red"
}
]
}
game["suspects"] //[{name: "Rusty"}, {name: "Miss Scarlet"}]
@BIANCAGANDO
FEM 2017
Exercise
@BIANCAGANDO
FEM 2017
const game = {
'suspects': [
{
name: "Rusty",
color: "orange"
}, {
name: "Miss Scarlet",
color: "red"
}
]
}
Loop through the suspects array
Exercise
@BIANCAGANDO
FEM 2017
const game = {
'suspects': [
{
name: "Rusty",
color: "orange"
}, {
name: "Miss Scarlet",
color: "red"
}
]
}
Loop through all the properties of the suspect objects in the suspects array, mark them if you think they are guilty.
Exercise
@BIANCAGANDO
FEM 2017
var suspects = [
{
name: "Rusty",
color: "orange"
}, {
name: "Miss Scarlet",
color: "red"
}
]
Destructure this nested data structure into two variables with the strings 'red' and 'orange'.
Notes: ACCESS & ASSIGNMENT
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
@BIANCAGANDO
FEM 2017
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'];
@BIANCAGANDO
FEM 2017
LIST TRANSFORMATIONS
function CreateSuspectObjects(name) {
return {
name: name,
color: name.split(' ')[1],
//should be 1, not 2. Previous slide was a trick!
speak() {
console.log("my name is ", name);
}
};
};
var suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White'];
@BIANCAGANDO
FEM 2017
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 = [];
@BIANCAGANDO
FEM 2017
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);
}
@BIANCAGANDO
FEM 2017
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]));
}
@BIANCAGANDO
FEM 2017
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) {
let suspectObj = CreateSuspectObjects(name);
suspectsList.push(suspectObj);
});
@BIANCAGANDO
FEM 2017
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));
});
@BIANCAGANDO
FEM 2017
_.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).
@BIANCAGANDO
FEM 2017
_.each() usage
var rooms = ['observatory','ballroom', 'library'];
var logger = function(val){
console.log(val);
};
_.each(rooms, logger);
//_.each(list,iterator)
@BIANCAGANDO
FEM 2017
var rooms = ['observatory','ballroom', 'library'];
//_.each(list,iterator)
@BIANCAGANDO
FEM 2017
_.each() usage
var rooms = ['observatory','ballroom', 'library'];
var logger = function(val){
console.log(val);
};
//_.each(list,iterator)
@BIANCAGANDO
FEM 2017
_.each() usage
var rooms = ['observatory','ballroom', 'library'];
var logger = function(val){
console.log(val);
};
//_.each(list,iterator)
@BIANCAGANDO
FEM 2017
_.each() usage
_.each() usage
var rooms = ['observatory','ballroom', 'library'];
var logger = function(val){
console.log(val);
};
//_.each(list,iterator)
@BIANCAGANDO
FEM 2017
Exercise
Complete the rest of this function so that it works as described in the previous slides:
_.each = function(list, callback) {
//... TODO
}
@BIANCAGANDO
FEM 2017
Exercise: Write w/ 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]));
}
@BIANCAGANDO
FEM 2017
_.map() / .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).
@BIANCAGANDO
FEM 2017
_.map() USAGE
const weapons = ['candlestick', 'lead pipe', 'revolver'];
//_.map(list, iterator)
@BIANCAGANDO
FEM 2017
_.map() USAGE
const weapons = ['candlestick', 'lead pipe', 'revolver'];
const makeBroken = function(item){
return `broken ${item}`;
};
//_.map(list, iterator)
@BIANCAGANDO
FEM 2017
_.map() USAGE
const weapons = ['candlestick', 'lead pipe', 'revolver'];
const makeBroken = function(item){
return `broken ${item}`;
};
const brokenWeapons = _.map(weapons, makeBroken);
brokenWeapons;
// [
// 'broken candlestick',
// 'broken lead pipe',
// 'broken revolver'
// ]
//_.map(list, iterator)
@BIANCAGANDO
FEM 2017
_.map vs _.each
function CreateSuspectObjects(name) {
return {
name: name,
color: name.split(' ')[1],
speak() {log(`my name is ${this.name}`);}
};
};
var suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White'];
var suspectsList = _.map(suspects, function (name) {
return CreateSuspectObjects(name);
});
_.each(suspects, function(suspect) {
suspect.speak()
});
@BIANCAGANDO
FEM 2017
Looping with _.map
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 suspectObjectList = [];
_.each(suspects, function(suspect) {
suspectObjectList.push(CreateSuspectObjects(suspect))
});
@BIANCAGANDO
FEM 2017
Looping with _.map
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 suspectObjectList = _.map(suspects, function(suspect) {
CreateSuspectObjects(suspect)
});
@BIANCAGANDO
FEM 2017
Recap
What do we know so far?
- Things aren't always as they seem
- Our detective team has a lot of skills and experience working with and manipulating data...
- They've been hard at work last night!
@BIANCAGANDO
FEM 2017
Just in...
@BIANCAGANDO
FEM 2017
const videoData = [
{
name: 'Miss Scarlet',
present: true,
rooms: [
{kitchen: false},
{ballroom: false},
{conservatory: false},
{'dining room': false},
{'billiard room': false},
{library: false}
]
},
{
name: 'Mrs. White',
present: false,
rooms: [
{kitchen: false},
{ballroom: false},
{conservatory: false},
{'dining room': false},
{'billiard room': false},
{library: false}
]
},
{
name: 'Reverend Green',
present: true,
rooms: [
{kitchen: false},
{ballroom: false},
{conservatory: false},
{'dining room': false},
{'billiard room': false},
{library: false}
]
},
{
name: 'Rusty',
present: false,
rooms: [
{kitchen: false},
{ballroom: false},
{conservatory: false},
{'dining room': false},
{'billiard room': false},
{library: false}
]
},
{
name: 'Colonel Mustard',
present: true,
rooms: [
{kitchen: false},
{ballroom: false},
{conservatory: false},
{'dining room': false},
{'billiard room': false},
{library: false}
]
},
{
name: 'Professor Plum',
present: true,
rooms: [
{kitchen: false},
{ballroom: false},
{conservatory: false},
{'dining room': false},
{'billiard room': false},
{library: false}
]
}
];
Exercise: _.filter()
@BIANCAGANDO
FEM 2017
We are going to want to filter by those who were present, but first we need to write our filter function:
_.filter(arr, callback) {
//...
}
Exercise: _.filter()
@BIANCAGANDO
FEM 2017
Filter the video data by the people who were present on the night of the murder!
FUNCTIONS
ANATOMY
@BIANCAGANDO
FEM 2017
Exercise Scavenger Hunt
@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!');
});
Find:
Definitions
Fn Names
Invocations
Arguments
Parameters
Fn Bodies
Return Values
Side Effects
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!');
});
ES6: Arrow Functions
@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!');
});
Exercise: project
@BIANCAGANDO
FEM 2017
Filter and then map this data
structure to get the names of
the final suspects to send back
to the team:
QUICK REVIEW
@BIANCAGANDO
FEM 2017
const createTuple = (a, b, c, d) => {
return [[a, c],[ b, d]];
}
createTuple('It', 'be', 'could', 'anyone', 'no one');
// => ??
Spread
@BIANCAGANDO
FEM 2017
const createTuple = (a, b, c, ...d) => {
return [[a, c],[ b, d]];
}
createTuple('It', 'be', 'could', 'anyone', 'no one');
// => ??
ARGUMENTS KEYWORD
@BIANCAGANDO
FEM 2017
const createTuple = (a, b, c, d) => {
console.log(arguments);
return [[a, c],[ b, d]];
}
createTuple('It', 'be', 'could', 'anyone', 'no one');
ARGUMENTS KEYWORD
@BIANCAGANDO
FEM 2017
const createTuple = function(a, b, c, ...d) {
console.log(arguments);
//['It', 'be', 'could', 'anyone', 'no one']
return [[a, c],[ b, d]];
}
createTuple('It', 'be', 'could', 'anyone', 'no one');
DEFAULT PARAMETERS
@BIANCAGANDO
FEM 2017
const add = function(a , b = 2) {
console.log(arguments); //logs [3]
return a + b;
};
add(3); //5??
Exercise
write this function in ES5:
@BIANCAGANDO
FEM 2017
const add = function(a , b = 2){
console.log(arguments); //logs [3]
return a + b;
};
add(3); //5??
ARRAY-LIKE OBJECT
@BIANCAGANDO
FEM 2017
const constructArr = function() {
const arr = Array.prototype.slice.call(arguments);
arr.push('the billiards room?');
return arr.join(' ');
};
constructArr('was', 'it', 'in');
ARRAY-LIKE OBJECT
@BIANCAGANDO
FEM 2017
const constructArr = function() {
const arr = Array.from(arguments);
arr.push('the billiards room?');
return arr.join(' ');
};
constructArr('was', 'it', 'in');
Exercise:
implement _.from()
@BIANCAGANDO
FEM 2017
const from = arr => {
return Array.prototype.slice.call(arr)
}
P.S. FUNCTIONS ARE OBJECTS!
@BIANCAGANDO
FEM 2017
const add = function(a, b){
return a + b;
};
add.example = 'testing 123!';