Javascript - OOP Part 2

Leon Noel

#100Devs

Cut class 'cause it wasn't 'bout cash
School wasn't no fun, couldn't bring my gun

Know a change gon' come like Obama 'nem say
But they shooting everyday 'round my mama 'nem way

Agenda

  • Questions? 

  • Let's Talk -  #100Devs

  • Learn - Objects

  • Learn - Basic OOP Principles

  • Do - Work In Teams: The Four Pillars

  • Do - Work In Teams: Tic-tac-toe

  • Homework - Object City Yall

Questions

About last class or life

Checking In

Like and Retweet the Tweet

!checkin

!newsletter

Networking - Next Week

Client Deadline: March 5th

Client Alternatives

Grassroots Volunteer*

Free Software / Open Source

GIT BOWL

SUNDAY
1:00pm EST

Never Miss The Stream Team

Welcome, verolafox

Friday @ 11:00am ET! 

Objects

What are objects?

USE
UNDERSTAND
BUILD

Finna Make Sum Nerds Angry

Objects

  • Objects are a collection of variables and functions!

  • Objects represent the attributes and behavior of something used in a program

  • Object variables are called properties and object functions are called methods

  • Objects store "keyed" collections

Think of a physical object

What are it's attributes and behaviors? 

How about a stopwatch

What are its properties and methods? 

Stopwatch Object

let stopwatch = {}

stopwatch.currentTime = 12

stopwatch.tellTime = function(time){
  console.log(`The current time is ${time}.`)
}

stopwatch.tellTime(stopwatch.currentTime)

Notation?

Objects

What if we want to make

a lot of objects?

How much money you got? How many problems you got? How many people done doubted you? Left you out to rot?

Car Factory?

Constructors then Classes

Car Factory

Constructor

function MakeCar(carMake,carModel,carColor,numOfDoors){
  this.make = carMake
  this.model = carModel
  this.color = carColor
  this.doors = numOfDoors
  this.honk = function(){
    alert('BEEP BEEP FUCKER')
  }
  this.lock = function(){
    alert(`Locked ${this.doors} doors!`)
  }
}

let hondaCivic = new MakeCar('Honda','Civic','Silver', 4)

let teslaRoadster = new MakeCar('Tesla','Roadster', 'Red', 2)

Car Factory

Look Ma! New syntax!

class MakeCar{
  constructor(carMake,carModel,carColor,numOfDoors){
    this.make = carMake
    this.model = carModel
    this.color = carColor
    this.doors = numOfDoors
  }
  honk(){
    alert('BEEP BEEP FUCKER')
  }
  lock(){
    alert(`Locked ${this.doors} doors!`)
  }
}

let hondaCivic = new MakeCar('Honda','Civic','Silver', 4)

let teslaRoadster = new MakeCar('Tesla','Roadster', 'Red', 2)

Classes are like templates for objects!

BUT WHY?

Why Use Objects?
Why Would We Need A Factory?

What if there was a system, a paradigm, a set of rules, an agreed upon way to structure our code that:

 

Made it easier to add new stuff

Made it easier to read through what was already coded

And made it so you were not afraid to make changes

 

Music & Light Warning - Next Slide

OOP BABY

OBJECT ORIENTED PROGRAMING 

Let's See Some Code

let hourlyRate = 250
let hours = 160
let taxRate = .35

function calculateProfit(rate, numOfHours, taxes){
  return rate * numOfHours * (1 - taxes)
}

let profit = calculateProfit(hourlyRate, hours, taxRate)

console.log(profit)

Is it easy to add new features and functionality?

let hourlyRate = 250
let hours = 160
let taxRate = .35

function calculateProfit(rate, numOfHours, taxes){
  return rate * numOfHours * (1 - taxes)
}

function holdForTaxes(profitMade){
  return hourlyRate * hours - profitMade
}

let profit = calculateProfit(hourlyRate, hours, taxRate)

let taxesHeld = holdForTaxes(profit)

console.log(profit)

console.log(taxesHeld)

Can another developer look at my code and understand what is happening?

let hourlyRate = 250
let hours = 160
let taxRate = .35

function calculateProfit(rate, numOfHours, taxes){
  return rate * numOfHours * (1 - taxes)
}

function holdForTaxes(profitMade){
  return hourlyRate * hours - profitMade
}

let profit = calculateProfit(hourlyRate, hours, taxRate)

let taxesHeld = holdForTaxes(profit)

console.log(profit)

console.log(taxesHeld)
let hourlyRate = 250
let hours = 160
let taxRate = .35

function calculateProfit(rate, numOfHours, taxes){
  return rate * numOfHours * (1 - taxes)
}

let profit = calculateProfit(hourlyRate, hours, taxRate)

console.log(profit)

Can I make changes without losing sleep at night? 

let hourlyRate = 250
let hours = 160
let taxRate = .35

function calculateProfit(rate, numOfHours, taxes){
  return rate * numOfHours * (1 - taxes)
}

function holdForTaxes(profitMade){
  return hourlyRate * hours - profitMade
}

let profit = calculateProfit(hourlyRate, hours, taxRate)

let taxesHeld = holdForTaxes(profit)

console.log(profit)

console.log(taxesHeld)

DATA & FUNCTIONALITY

let hourlyRate = 250
let hours = 160
let taxRate = .35

DATA

Functionality

function calculateProfit(rate, numOfHours, taxes){
  return rate * numOfHours * (1 - taxes)
}

let seriousBusinessPerson = {
  hourlyRate: 250,
  hours: 160,
  taxRate: .35,
  calculateProfit: function() {
    return this.hourlyRate * this.hours * (1 - this.taxRate)
  }
}

Is it easy to add new features and functionality?


let seriousBusinessPerson = {
  hourlyRate: 250,
  hours: 160,
  taxRate: .35,
  calculateProfit: function() {
    return this.hourlyRate * this.hours * (1 - this.taxRate)
  }
}

let seriousBusinessPerson = {
  hourlyRate: 250,
  hours: 160,
  taxRate: .35,
  calculateProfit: function() {
    return this.hourlyRate * this.hours * (1 - this.taxRate)
  }
  calculateTaxesHeld: function(){
    return this.hourlyRate * this.hours - this.calculateProfit()
  }
}

Can another developer look at my code and understand what is happening?


let seriousBusinessPerson = {
  hourlyRate: 250,
  hours: 160,
  taxRate: .35,
  calculateProfit: function() {
    return this.hourlyRate * this.hours * (1 - this.taxRate)
  }
}

Can I make changes without losing sleep at night? 


let seriousBusinessPerson = {
  hourlyRate: 250,
  hours: 160,
  taxRate: .40, //changed
  calculateProfit: function() {
    return this.hourlyRate * this.hours * (1 - this.taxRate)
  }
}

This fusion of data and functionality into one object

Music & Light Warning - Next Slide

Encapsulation Baby

Encapsulation

The process of storing functions (methods) with their associated data (properties) - in one thing (object)*

*Nerds shaking violently

Is it easy to add new features and functionality?

Heats water for espresso and steam for your milk

Steam wand sucks...

What should the engineers do?

Do they get rid of the water boiler?

probably not...

At first, do they even need to think about the water boiler?

So the water boiling is abstracted?

Let's look at some code


function AgencyContractor(hourlyRate, hours, taxRate){
  this.hourlyRate = hourlyRate
  this.hours = hours
  this.taxRate = taxRate
  this.calculateProfit = function() {
    return this.hourlyRate * this.hours * (1 - this.taxRate)
  }
  this.invoiceClient = function(){
    return `Your invoice total is ${this.hourlyRate * this.hours}`
  }
}

let leon = new AgencyContractor(250,160,.35)
console.log( leon.invoiceClient() ) //40000
console.log( leon.hourlyRate ) //250
console.log( leon.calculateProfit() ) //26000

Ut Oh...

function AgencyContractor(hourlyRate, hours, taxRate){
  this.hours = hours
  this.taxRate = taxRate
  let rate = hourlyRate
  let calculateProfit = function() {
    return rate * this.hours * (1 - this.taxRate)
  }
  this.invoiceClient = function(){
    return `Your invoice total is ${rate * this.hours}`
  }
}

let leon = new AgencyContractor(250,160,.35)
console.log( leon.invoiceClient() ) //40000
console.log( leon.hourlyRate ) //undefined
console.log( leon.calculateProfit() ) 
//Uncaught TypeError: leon.calculateProfit is not a function

Better...

*Nerds shaking violently

So now my client can still get their invoice, but not see my hourly rate

Water boiling was hidden from the steam wand

Hourly rate was hidden from the client

Complex or unnecessary details are hidden

This enables you to implement things without understanding or even thinking about all the hidden complexity

Smaller more manageable pieces of code

Do stuff once

Music & Light Warning - Next Slide

Abstraction Baby

Abstraction

Hide details

and show essentials

SIMPLE, PREDICTABLE, MANAGEABLE

Let's Start A Farm

class Animal{
    constructor(name){
        this.name = name
    }
    speak(){
        console.log(`${this._name} makes a sound`)
    }
}

What if we want a bunch of different animals on the farm?

class Animal{
    constructor(name){
        this.name = name
    }
    speak(){
        console.log(`${this.name} makes a sound`)
    }
}
class Dog extends Animal{
    constructor(name,breed){
        super(name)
        this.breed = breed
    } 
}

let simba = new Dog('Simba', 'Sheperd')

We can extend animal

* If you find yourself starting to create a number of objects that have similar features, then creating a generic object type to contain all the shared functionality and inheriting those features in more specialized object types can be convenient and useful. 

We just eliminated a bunch of redundant code

AKA

Music & Light Warning - Next Slide

Inheritance BABY

Inheritance

Make a class from another class for a hierarchy of classes that share a set of properties and methods

Let's Code

Make A Child Class

Back To The Farm

New workers keep renaming animals in our system

 

 

class Animal{
    constructor(name){
        this.name = name
    }
    speak(){
        console.log(`${this.name} makes a sound`)
    }
}

let simba = new Animal('Simba')

simba.name // "Simba"

simba.name = 'Bob' //nothing happens

simba.name // "Bob"

What could help here?

class Animal{
    constructor(name){
        this._name = name
    }
    get name(){
        return this._name
    }
    speak(){
        console.log(`${this._name} makes a sound`)
    }
}

let simba = new Animal('Simba')

simba.name // "Simba"

simba.name = 'Bob'  //nothing happens

We just rescued a bunch of animals! 

How should we build out our system? 

Let's Code

Animal System

We want to do a morning roll call and fortunately Dr. Dolittle works here

ROLL CALL

let simba = new Dog('Simba','Shepard')
let machi = new Dog('The Machine','Pitbull')
let salem = new Cat('Salem', 'American Shorthair')

let farm = [simba,machi,salem]

for( a of farm ){
    a.speak()
}

//Simba barks
//Machi barks
//Salem Meows

Wait A Minute

for( a of farm ){
    a.speak()
}

//Simba barks
//Machi barks
//Salem Meows

 Code written to use an interface automatically knows how to work with any number of different objects that provide the interface

Sibling descendants of a base class will all have the same interface but varying implementations

When you are not sure of the objects type at runtime and the most specific method is called.

Therefore the behavior of the method called may differ, depending on the objects type at runtime

for( a of farm ){
    if(a instanceof Dog){
      console.log('Bark')
	}else if (a instanceof Cat){
      console.log('Meow')         
    }
}

//Simba barks
//Machi barks
//Salem Meows

Disgusting

Why?

 

Provides a way to perform a single action in different forms.

 

Provides an ability to call the same method on different JavaScript objects.

Instead of conditionals and switch cases

Music & Light Warning - Next Slide

POLYMORPHISM BABY

The Four Pillars

What if they actually made any sense...

Encapsulation

The process of storing functions (methods) with their associated data (properties) in one thing (object)

BUT WHY?

Made it easier to add new stuff

 

Made it easier to read through what was already coded

 

And made it so you were not afraid to make changes

Abstraction

Hide details

and show essentials

BUT WHY?

Smaller more manageable pieces of code

Helps you to split the complexity your software project into manageable parts

Make code changes and still sleep at night

Inheritance

Make a class from another class for a hierarchy of classes that share a set of properties and methods

BUT WHY?

Helps you eliminate redundant code

Polymorphism

 Code written to use an interface automatically knows how to work with any number of different objects that provide the interface

BUT WHY?

Helps you avoid if/else and switch cases

Makes your code more reusable

 

Supports The

Other Pillars

Group Work

https://live.remo.co/e/100devs-networking-night-group-0
https://live.remo.co/e/100devs-networking-night-group-0-1
If Remo does not work for you, please jump into one of our

Discord Voice Channels!

Talk Through OOP

Right Of Passage

https://live.remo.co/e/100devs-networking-night-group-0
https://live.remo.co/e/100devs-networking-night-group-0-1
If Remo does not work for you, please jump into one of our

Discord Voice Channels!

Get It To Work 

 

Then:
 

Make it easier to add new stuff

 

Make it easier to read through what was already coded

 

And make it so you are not afraid to make changes

Homework

 

DO: Please review, play, and break the code we go over tonight.

Get lost in it, come with questions, and ready to review on Thursday.
DO: Get a paid client, Volunteer, or Contribute To Free Software
DO: FINISH Professional Checklist 

Want To Push (Due: Tues. May 5th)?
Do: Codewars Array Ladder (search array problems) - 8kyu, 7kyu, 6kyu, 7kyu, 8kyu  

#100Devs - Javascript OOP Part 2 (cohort 2)

By Leon Noel

#100Devs - Javascript OOP Part 2 (cohort 2)

Class 31 of our Free Web Dev Bootcamp for folx affected by the pandemic. Join live T/Th 6:30pm ET leonnoel.com/twitch and ask questions here: leonnoel.com/discord

  • 3,269