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

Conclusion