JavaScript Fundamentals
Objects, Arrays, and Functions

Hi, I'm Bianca!

... Get clear on how objects and arrays work the way they do
... Master using callbacks in your code and methods like reduce
... Implement internals of JS methods
... Understand commons gotchas when using functions
We will...

What happened
to Mr. Body?

Sincere, not serious.
This is an interactive course.
Most of this course will be live-coded so this slide deck will not be used often.
There will be uncomfortable moments!
Expect to have to think critically, answer questions, ask questions.

Objects
DATA STRUCTURES
Memory
Model
DATA STRUCTURES
const who = {
name: "Mrs. White"
};

const who = {
name: "Mrs. White"
};
const who = {};
who.name = "Mrs. White";

const who = {
name: "Mrs. White"
};
const who = {};
who.name = "Mrs. White";
who
"name" :
"Mrs. White"

who
"name" :
"Mrs. White"

const who = {
name: "Mrs. White"
};
who.name; // → ?
const suspect = who.name;
who.name = "Mr. Green";
suspect; // → ?
suspect = "Mr. Green";
suspect; // → ?
who.story; // → ?
who
"name" :
"Mrs. White"

suspect
"Mrs. White"
const who = {
name: "Mrs. White"
};
who.name; // → ?
const suspect = who.name;
who.name = "Mr. Green";
suspect; // → ?
suspect = "Mr. Green";
who.story; // → ?
who
"name" :
"Mrs. White"
"Mr.Green"

suspect
"Mrs. White"
const who = {
name: "Mrs. White"
};
who.name; // → ?
const suspect = who.name;
who.name = "Mr. Green";
suspect; // → ?
suspect = "Mr. Green";
suspect; // → ?
who.story; // → ?
who
"name" :
"Mrs. White"
"Mr.Green"

suspect
"Mrs. White"
const who = {
name: "Mrs. White"
};
who.name; // → ?
const suspect = who.name;
who.name = "Mr. Green";
suspect; // → ?
suspect = "Mr. Green";
suspect; // → ?
who.story; // → ?
who
"name" :
"Mrs. White"
"Mr.Green"

suspect
"Mrs. White"
const who = {
name: "Mrs. White"
};
who.name; // → ?
const suspect = who.name;
who.name = "Mr. Green";
suspect; // → ?
suspect = "Mr. Green";
suspect; // → ?
who.story; // → ?

who
"name" :
"Mrs. White"
"Mr.Green"

suspect
const who = {
name: "Mrs. White"
};
who.name; // → ?
let suspect = who.name;
who.name = "Mr. Green";
suspect; // → ?
suspect = "Mr. Green";
suspect; // → ?
who.story; // → ?
"Mrs. White"
who
"name" :
"Mrs. White"
"Mr.Green"

suspect
const who = {
name: "Mrs. White"
};
who.name; // → ?
let suspect = who.name;
who.name = "Mr. Green";
suspect; // → ?
suspect = "Mr. Green";
suspect; // → ?
who.story; // → ?
"Mrs. White"
"Mr.Green"
who
"name" :
"Mrs. White"
"Mr.Green"

suspect
const who = {
name: "Mrs. White"
};
who.name; // → ?
let suspect = who.name;
who.name = "Mr. Green";
suspect; // → ?
suspect = "Mr. Green";
suspect; // → ?
story; // → ?
"Mrs. White"
"Mr.Green"

Arrays
DATA STRUCTURES

const who = {};
who.name = "Professor Plum";
let suspect = who.name;
who.name = "Mrs. Scarlett";
suspect; // → ?
suspect = "Mrs. Scarlett";
suspect; // → ?
who.story; // → ?

who
"name" :
"Prof. Plum"
"Mrs. Scarlett"
suspect

const who = {};
who.name = "Professor Plum";
let suspect = who.name;
who.name = "Mrs. Scarlett";
suspect; // → ?
suspect = "Mrs. Scarlett";
suspect; // → ?
who.story; // → ?
"Prof. Plum"
"Mrs. Scarlett"

const who = [];
who.name = "Professor Plum";
let suspect = who.name;
who.name = "Mrs. Scarlett";
suspect; // → ?
suspect = "Mrs. Scarlett";
suspect; // → ?
who.story; // → ?
const who = [];
who.name = "Professor Plum";
let suspect = who.name;
who.name = "Mrs. Scarlett";
suspect; // → ?
suspect = "Mrs. Scarlett";
suspect; // → ?
who.story; // → ?
When are some other times you have seen other dots in JS?

who
"name" :
suspect

"Prof. Plum"
"Mrs. Scarlett"
"Prof. Plum"
"Mrs. Scarlett"
const who = [];
who.name = "Mrs. Scarlett";
who[0]; // → ?
who[0] = "I was not in the Billiard Room.";
who[0]; // → ?
who[plea] = "I would never!";
who
"name" :
"Mrs. Scarlett"
who

const who = [];
who.name = "Mrs. Scarlett";
who[0]; // → ?
who[0] = "I was not in the Billiard Room.";
who[0]; // → ?
who[plea] = "I would never!";
"name" :
"Mrs. Scarlett"
who
"0" :

"I was not in..."
const who = [];
who.name = "Mrs. Scarlett";
who[0]; // → ?
who[0] = "I was not in the Billiard Room.";
who[0]; // → ?
who[plea] = "I would never!";

"name" :
"Mrs. Scarlett"
"0" :

"I was not in..."
who
const who = [];
who.name = "Mrs. Scarlett";
who[0]; // → ?
who[0] = "I was not in the Billiard Room.";
who[0]; // → ?
who[plea] = "I would never!";
const plea = "didShe";
"name" :
"Mrs. Scarlett"
"0" :

"I was not in..."
??
plea

who
const who = [];
who.name = "Mrs. Scarlett";
who[0]; // → ?
who[0] = "I was not in the Billiard Room.";
who[0]; // → ?
const plea = "didShe";
who[plea] = "I would never!";
"name" :
"Mrs. Scarlett"
"0" :

"I was not in..."
plea
"didShe"
"didShe" :
"I would never!"
who
const who = [];
who.name = "Mrs. Scarlett";
who[0]; // → ?
who[0] = "I was not in the Billiard Room.";
who[0]; // → ?
who["plea"] = "I would never!";
"name" :
"Mrs. Scarlett"
"0" :

"I was not in..."
"plea" :
"I would never!"
who
const who = [];
who.name = "Mrs. Scarlett";
who[0]; // → ?
who[0] = "I was not in the Billiard Room.";
who[0]; // → ?
who.plea = "I would never!";
"name" :
"Mrs. Scarlett"
"0" :

"I was not in..."
"plea" :
"I would never!"
who
const who = {};
const where = '^&*';
who['name'] = 'Mrs. Peacock';
who[0] = 'in the hall';
who['^&*'] = 'I\'m not sure what you are implying.';
who['^&*']; // → ?
who[2 - 2] = 'in the library';
who[3 + 2 - 5]; // → ?
who[where]; // → ?
"name" :
"Mrs. Peacock"
"0" :
"in the hall"
"^&*" :
"I'm not sure..."
who

"in the library"
where
"^&*"
THE RULES
Dots
Brackets
strings
numbers
quotations
weird characters
expressions
strings
numbers
variables
weird characters
expressions
Iteration
DATA STRUCTURES
Maps and Sets
DATA STRUCTURES
Introduction
FUNCTIONS
Callbacks + Higher Order Functions
FUNCTIONS
1. HOFs take a function as an input.
element.addEventListener("change", () => {
console.log("Our evidence is updated");
});
2. HOFs return a function as the output
const newClue = (name) => {
const length = name.length;
return (weapon) => {
const clue = length + weapon.length;
return !!(clue % 1);
};
};
const ifElse = (condition, isTrue, isFalse) => {
return condition ? isTrue() : isFalse();
};
ifElse(isGuilty,
() => { console.log('GUILTY!!');},
() => { console.log('NOT GUILTY');}
);
const ifElse = (condition, isTrue, isFalse) => {
return condition ? isTrue() : isFalse();
};
const logTrue = () => { console.log('GUILTY!!');}
const logFalse = () => { console.log('NOT GUILTY');}
ifElse(true, logTrue, logFalse);
const ifElse = (condition, isTrue, isFalse, p) => {
//How do we pass arguments?
return condition ? isTrue(p) : isFalse(p);
};
ifElse(true, fn1, fn2, 'HI');
const ifElse = (condition, isTrue, isFalse, ...args) => {
console.log(args); //['HI', 'BYE', 'HOLA']
return condition ?
isTrue(...args) : // isTrue('HI', 'BYE', 'HOLA')
isFalse(...args);
};
ifElse(true, fn1, fn2, 'HI', 'BYE', 'HOLA');
const ifElse = (condition, isTrue, isFalse) => {
const args = [].slice.call(arguments, 3);
return condition ?
isTrue.apply(this, args) :
isFalse.apply(this, args);
};
const logTrue = (msgs) => { console.log(msgs); };
const logFalse = (msgs) => { console.log(msgs); };
ifElse(true, logTrue, logFalse, 'a', 'b');
const ifElse = (condition, isTrue, isFalse) => {
const args = [].slice.call(arguments, 3);
return condition ?
isTrue.apply(this, args) :
isFalse.apply(this, args);
};
const logTrue = (msgs) => { console.log(msgs); };
const logFalse = (msgs) => { console.log(msgs); };
ifElse(true, logTrue, logFalse, 'a', 'b');

const ifElse = function(condition, isTrue, isFalse) {
const args = [].slice.call(arguments, 3);
return condition ?
isTrue.apply(this, args) :
isFalse.apply(this, args);
};
const logTrue = (msgs) => { console.log(msgs); };
const logFalse = (msgs) => { console.log(msgs); };
ifElse(true, logTrue, logFalse, 'a', 'b');
Scope
FUNCTIONS
const partition = (list, predicate) => {
const result = [[],[]];
const item = "Oh, hello there.";
result.forEach((item, index, list) => {
console.log(item); // ??
});
};
partition([1, 2, 3, 4], n => n % 2);
// → [[1, 3], [2, 4]]

Closure
FUNCTIONS
const clue = () => {
const msg = "Help! I think I found a clue!";
const logger = () => {
console.log(msg);
};
setTimeout(logger, 1000);
console.log("what happens first? this log or the halp above?");
};
clue();
// => ??
// => ??
const clue = () => {
const msg = "Help! I think I found a clue!";
const logger = () => {
console.log(msg);
};
setTimeout(logger, 1000);
console.log("What happens first? this log or the halp above?");
};
clue();
// => "What happens first? this log or the halp above?"
// => "Help! I think I found a clue!"
const clueCounter = (msg) => {
let count = 0;
const logger = () => {
console.log(`${msg} ${++count}`);
};
return logger;
};
const funcClueCounter1 = clueCounter('Clue #');
const clueCounter = (msg) => {
let count = 0;
const logger = () => {
console.log(`${msg} ${++count}`);
};
return logger;
};
const funcClueCounter1 = clueCounter('Clue #');
console.log(typeof funcClueCounter1); // => ??
const clueCounter = (msg) => {
let count = 0;
const logger = () => {
console.log(`${msg} ${++count}`);
};
return logger;
};
const funcClueCounter1 = clueCounter('Clue #');
console.log(typeof funcClueCounter1); // => function
const clueCounter = (msg) => {
let count = 0;
const logger = () => {
console.log(`${msg} ${++count}`);
};
return logger;
};
const funcClueCounter1 = clueCounter('Clue #');
const funcClueCounter2 = clueCounter('Another clue #');
console.log(typeof funcClueCounter1); // => function
const clueCounter = (msg) => {
let count = 0;
const logger = () => {
console.log(`${msg} ${++count}`);
};
return logger;
};
const funcClueCounter1 = clueCounter('Clue #');
const funcClueCounter2 = clueCounter('Another clue #');
console.log(typeof funcClueCounter1); // => function
console.log(funcClueCounter1 === funcClueCounter2); // => ??
const clueCounter = (msg) => {
let count = 0;
const logger = () => {
console.log(`${msg} ${++count}`);
};
return logger;
};
const funcClueCounter1 = clueCounter('Clue #');
const funcClueCounter2 = clueCounter('Another clue #');
console.log(typeof funcClueCounter1); // => function
console.log(funcClueCounter1 === funcClueCounter2); // => false
const clueCounter = (msg) => {
let count = 0;
const logger = () => {
console.log(`${msg} ${++count}`);
};
return logger;
};
const funcClueCounter1 = clueCounter('Clue #');
const funcClueCounter2 = clueCounter('Another clue #');
funcClueCounter1(), funcClueCounter1(), funcClueCounter1();
// => ??
const clueCounter = (msg) => {
let count = 0;
const logger = () => {
console.log(`${msg} ${++count}`);
};
return logger;
};
const funcClueCounter1 = clueCounter('Clue #');
const funcClueCounter2 = clueCounter('Another clue #');
funcClueCounter1(), funcClueCounter1(), funcClueCounter1();
// => "Clue # 1"
// => "Clue # 2"
// => "Clue # 3"
const clueCounter = (msg) => {
let count = 0;
const logger = () => {
console.log(`${msg} ${++count}`);
};
return logger;
};
const funcClueCounter1 = clueCounter('Clue #');
const funcClueCounter2 = clueCounter('Another clue #');
funcClueCounter1(), funcClueCounter1(), funcClueCounter1();
// => "Clue # 1"
// => "Clue # 2"
// => "Clue # 3"
funcClueCounter2();
// => ??
const clueCounter = (msg) => {
let count = 0;
const logger = () => {
console.log(`${msg} ${++count}`);
};
return logger;
};
const funcClueCounter1 = clueCounter('Clue #');
const funcClueCounter2 = clueCounter('Another clue #');
funcClueCounter1(), funcClueCounter1(), funcClueCounter1();
// => "Clue # 1"
// => "Clue # 2"
// => "Clue # 3"
funcClueCounter2();
// => "Another clue # 1"
const cC = (msg) => {
let count = 0;
const lg = () => {
console.log(`${msg} ${++count}`);
};
return lg;
};
const cc1 = cC('Clue #');
const cc2 = cC('Another clue #');
cc1(), cc1(), cc1();
cc2();
fn { ... }
cC
lg() { ... }
cc1
"Clue #"
msg
lg() { ... }
lg
0
count
lg() { ... }
cc2
"Anot.."
msg
lg() { ... }
lg
0
count
const cC = (msg) => {
let count = 0;
const lg = () => {
console.log(`${msg} ${++count}`);
};
return lg;
};
const cc1 = cC('Clue #');
const cc2 = cC('Another clue #');
cc1(), cc1(), cc1();
cc2();
lg() { ... }
cc1
"Clue #"
msg
lg() { ... }
lg
0
count
1
2
3
lg() { ... }
cc2
"Anot.."
msg
lg() { ... }
lg
0
count
1
const countClues = () => {
let n = 0;
return {
count: () => n++,
reset: () => n = 0
};
};

const countClues = () => {
let n = 0;
return {
count: () => n++,
reset: () => n = 0
};
};

fn { ... }
countClues
const countClues = () => {
let n = 0;
return {
count: () => n++,
reset: () => n = 0
};
};
const c = countClues();

fn { ... }
countClues
0
n
{ count: fn,
reset: fn }
c

const countClues = () => {
let n = 0;
return {
count: () => n++,
reset: () => n = 0
};
};
const c = countClues();
console.log(c);
{
count: () => n++,
reset: () => n = 0
}

fn { ... }
countClues
0
n
{ count: fn,
reset: fn }
c

const countClues = () => {
let n = 0;
return {
count: () => n++,
reset: () => n = 0
};
};
const c = countClues();
const d = countClues();

fn { ... }
countClues
0
n
{ count: fn,
reset: fn }
c
d
0
n
{ count: fn,
reset: fn }


const countClues = () => {
let n = 0;
return {
count: () => n++,
reset: () => n = 0
};
};
const c = countClues();
const d = countClues();
c.count();
-> ??

fn { ... }
countClues
0
n
{ count: fn,
reset: fn }
c
d
0
n
{ count: fn,
reset: fn }



const countClues = () => {
let n = 0;
return {
count: () => n++,
reset: () => n = 0
};
};
const c = countClues();
const d = countClues();
c.count();
-> 0

fn { ... }
countClues
1
n
{ count: fn,
reset: fn }
c
d
0
n
{ count: fn,
reset: fn }


const countClues = () => {
let n = 0;
return {
count: () => ++n,
reset: () => n = 0
};
};
const c = countClues();
const d = countClues();
c.count();
-> 1

fn { ... }
countClues
1
n
{ count: fn,
reset: fn }
c
d
0
n
{ count: fn,
reset: fn }


const countClues = () => {
let n = 0;
return {
count: () => ++n,
reset: () => n = 0
};
};
const c = countClues();
const d = countClues();
c.count(), c.count();
d.count();

fn { ... }
countClues
2
n
{ count: fn,
reset: fn }
c
d
0
n
{ count: fn,
reset: fn }


-> ??

1
1
const countClues = () => {
let n = 0;
return {
count: () => ++n,
reset: () => n = 0
};
};
const c = countClues();
const d = countClues();
c.count(), c.count();
d.count();

fn { ... }
countClues
2
n
{ count: fn,
reset: fn }
c
d
0
n
{ count: fn,
reset: fn }


-> 1

1
1