✒️
SEI 802
  • Introduction
  • About These Notes
  • Syllabus
  • Development Workflow
    • Installfest
      • Mac OSX
      • Linux
      • Git Configuration
      • Sublime Packages
    • Command Line
      • The Terminal
      • Filesystem Navigation
      • File Manipulation
      • Additional Topics
    • Intro to Git
      • Version Control
      • Local Git
      • Remote Git
      • Git Recipes
    • Group Collaboration
      • Git Workflows
      • Project Roles and Tools
    • VS Code Tips & Tricks
  • HTML/CSS
    • HTML
    • CSS Selectors
    • CSS Box Model and Positioning
      • Box Model
      • Display and Positioning
      • Flexbox
      • Grid
      • Flexbox & Grid Games
      • Floats and Clears
      • Additional Topics
    • Advanced CSS
      • Responsive Design
      • Pseudo-Classes/Elements
      • Vendor Prefixes
      • Custom Properties
      • Additional Topics
    • Bootstrap
    • CSS Frameworks
    • Accessibility
  • JavaScript
    • Primitives
    • Arrays
    • Objects
    • Control Flow
      • Boolean Expressions
      • Conditionals
      • Loops
      • Promises
    • Functions
      • Callbacks
      • Timing Functions
      • Iterators
    • DOM and Events
    • DOM Manipulation
    • HTML5 Canvas
    • How To Reduce Redundancy
    • (2019) JavaScript OOP
    • (2016) OOP with Classes
    • (1995) OOP with Prototypes
      • Constructors
      • Prototypes
    • Intro to TDD
    • Scoping
    • Inheritance
      • Prototypal Inheritance
      • Call, Apply, and other Functions
      • ES6 Inheritance
      • Resources
    • Custom Node Modules
    • Additional Topics
      • AJAX, Fetch, and Async/Await
      • AJAX w/JSON and Localstorage
        • AJAX w/JSON
        • Local Storage
      • Async module
      • Data Scraping
  • jQuery
    • Intro
      • DOM Manipulation
      • Reddit Practice
      • Styling
      • Events
    • Plugins
    • AJAX
  • APIs
    • Fetch
    • AJAX w/jQuery
    • AJAX w/Fetch
  • Databases
    • Intro to SQL
    • Advanced SQL
    • MongoDB
      • Intro to NoSQL
      • CRUD in MongoDB
      • Data Modeling
      • Intermediate Mongo
  • Node/Express
    • Node
      • Intro to Node
      • Node Modules
      • Node Package Manager (NPM)
    • Express
      • Intro to Express
        • Routes
        • Views
        • Templates
        • Layouts and Controllers
        • CRUD & REST
          • Get and Post
          • Put and Delete
      • APIs with Express (request)
      • APIs with Express (axios)
    • Sequelize
      • Terminology
      • Setup
      • Using Models
      • Seeding Data
      • Validations and Migrations
      • Resources
      • 1:M Relationships
      • N:M Relationships
    • Express Authentication
      • Research Components
      • Code Components
      • Auth in Theory
        • Sessions
        • Passwords
        • Middleware
        • Hooks
      • Auth in Practice
        • Create the User
        • User Signup
        • Sessions
        • User Login
        • Authorization and Flash messages
    • Testing with Mocha and Chai
    • Mongoose
      • Mongoose Associations
    • JSON Web Tokens
      • Codealong
    • Additional Topics
      • oAuth
      • Geocoding with Mapbox
      • Geocoding and Google Maps
      • Cloudinary
      • Websockets with Socket.io
      • SASS
  • Ruby
    • Intro to Ruby
    • Ruby Exercises
    • Ruby Classes
    • Ruby Testing with Rspec
    • Ruby Inheritance
    • Ruby Data Scraping
  • Ruby on Rails
    • Intro to Rails
    • APIs with Rails
    • Asset Pipeline
    • Rails Auth and 1-M
      • Auth Components
    • Rails N:M
    • ActiveRecord Polymorphism
    • Additional Topics
      • oAuth
      • SASS
      • Rails Mailers
      • Cloudinary
      • Jekyll
  • React (Updated 2019)
    • ES6+/ESNext
      • Const and Let
      • Arrow Functions
      • Object Literals and String Interpolation
      • ES6 Recap
      • ES6 Activity
    • Intro to React
      • Create React App
      • Components and JSX
      • Virtual DOM
      • Props
      • Dino Blog Activity
      • Nested Components
      • Lab: LotR
    • React State
      • Code-Along: Mood Points
      • Code-Along: Edit Dino Blog
      • Lab: Simple Calc
      • Lifting State
    • React Router
      • Browser History/SPAs
      • React Router (lesson and full codealong)
      • Router Lab
    • Fetch and APIs
      • APIs with Fetch and Axios
      • Fetch the Weather
    • React Hooks
    • React LifeCycle
      • Lab: Component LifeCycle
    • React Deployment
    • Additional Topics
      • React Frameworks
        • Material UI Theming
      • Typescript
        • More Types and Syntax
        • Tsconfig and Declaration Files
        • Generics with Linked List
      • Redux
      • TypeScript
      • Context API
      • React Native
  • Meteor
  • Deployment and Config
    • Deploy - Github Pages
    • Deploy - Node/Sequelize
    • Deploy - Node/MongoDB
    • Deploy React
    • Deploy - Rails
      • Foreman (Environment Variables)
    • Deploy - AWS Elastic Beanstalk
    • Deploy - S3 Static Sites
    • Deploy - Django
    • Deploy - Flask
  • Data Structures and Algorithms
    • Recursion
    • Problem Solving - Array Flatten
    • Binary Search
    • Algorithm Complexity
    • Stacks and Queues
    • Bracket Matching
    • Ruby Linked Lists
      • Sample Code
      • Beginner Exercises
      • Advanced Exercises
    • JS Linked Lists
      • Sample Code
      • Beginner Exercises
      • Beginner Solutions
    • Hash Tables
    • Intro to Sorting
    • Insertion Sort
    • Bucket Sort
    • Bubble Sort
    • Merge Sort
    • Quick Sort
    • Heap Sort
    • Sorting Wrapup
    • Hashmaps
    • Trees and Other Topics
  • Python
    • Python Installation
    • Intro to Python
    • Python Lists
    • Python Loops
    • Python Dictionaries
    • Python Sets and Tuples
    • Python Cheatsheet
    • Python Functions
    • Python Classes
    • Python Class Inheritance
    • Intro to Flask
    • Intro to SQLAlchemy
      • Flask and SQLAlchemy
    • Using PyMongo
    • Intro to Django
    • CatCollector CodeAlong
      • URLs, Views, Templates
      • Models, Migrations
      • Model Form CRUD
      • One-to-Many Relations
      • Many-to-Many Relations
      • Django Auth
    • Django Cheatsheet
    • Django Auth
    • Django Polls App Tutorial
    • Django School Tool Tutorial
    • Django 1:M Relationships
    • Custom Admin Views
    • Data Structures and Algorithms
      • Recursion
      • Binary Search
      • Stacks and Queues
      • Linked Lists
      • Binary Trees
      • Bubble Sort
      • TensorFlow & Neural Networks
    • Adjacent Topics
      • Raspberry Pi
      • Scripting
  • Assorted Topics
    • History of Computer Science
    • Regular Expressions
    • Intro to WDI (Course Info)
    • Being Successful in WDI
    • Internet Fundamentals
      • Internet Lab
    • User Stories and Wireframing
      • Wireframing Exercise: Build an Idea
    • Post WDI
      • Learning Resources
      • Deliverables -> Portfolio
      • FAQ
  • Projects
    • Project 1
    • Project 2
    • Project 3
      • Project 3 Pitch Guidelines
    • Project 4
    • Past Projects
      • Project 1
      • Project 2
      • Project 3
      • Project 4
      • Portfolios
    • Post Project 2
    • MEAN Hackathon
      • Part 1: APIs
      • Part 2: Angular
    • Portfolio
  • Web Development Trends
  • Resources
    • APIs and Data
    • Tech Websites
    • PostgreSQL Cheat Sheet
    • Sequelize Cheat Sheet
    • Database Administration
  • Archived Section
    • (Archived) ReactJS
      • Intro to React
        • Todo List Codealong
        • Additional Topics
      • Deploy React
      • React with Gulp and Browserify
        • Setting up Gulp
        • Additional Gulp Tasks
      • React Router
        • OMDB Router
        • OMDB Search
        • Additional Resources
      • React Animations
        • CSS Animations
    • AngularJS
      • Intro to AngularJS
        • Components and SPA
        • Create an Angular App
      • Angular Directives and Filters
      • Angular Animation
      • Angular Bootstrap Directives
        • Bootstrap Modals
      • Angular $http
      • Angular Services
        • Service Recipes
        • ngResource
        • Star Wars Codealong
      • Angular Routing
      • Angular + Express
      • Angular Authentication
        • Additional Topics
      • Angular Components
      • Angular Custom Filters
      • Angular Custom Directives
Powered by GitBook
On this page
  • Objectives
  • Objects and Classes
  • Codealong: Write a basic class
  • Instantiating objects from classes
  • Class (static) vs Instance members
  • Inheritance
  • Principles of Object Oriented Programming
  • Exercise: Create Your Own JavaScript Class
  • Closing Thoughts

Was this helpful?

  1. JavaScript

(2019) JavaScript OOP

Objectives

  • Describe the difference between classes and objects

  • Use JavaScript syntax to define a class

  • Instantiate an object from a class

  • Explain the use of the constructor method

  • Utilize the this keyword in the scope of class variables and methods

  • Understand class variables and how they differ from instance variables

Objects and Classes

JavaScript is an object oriented programming language (or at least it does its best to approximate one). Object oriented programming is characterized by the creation and use of collections of data and behavior that act like everyday physical objects. Every day we interact with objects like chairs, beverages, cars, other people, etc. These objects have properties that define them and behaviors we can execute to interact with them. Over many years, programmers have found that designing systems to reflect discrete, everyday objects makes the systems easier to understand, write, test, and maintain.

You will hear people say that "everything is an object" in JavaScropt. What this means is that nearly every variable you declare already has a set of properties and functions that it can use because it is an object. Every string, number, array, object, etc has a set of behaviors and properties that are "baked-in" because they are instances of a class. For example, every string you declare is an instance of a built-in JavaScript String class and because of that you can use any of the built-in string functions like toUpperCase() and toLowerCase() on your own string.

Frequently, we want to design our own special data types that hold our own specific data and organize it in a certain way. JavaScript gives us a string and a number, but what if we want to store a bunch of data where each item contains a string and an number and a function that prints them out nicely? We can make a class for that and then each object we make from that class will have all that baked-in.

Codealong: Write a basic class

I like dogs. Here's what a Dog class definition might look like in JavaScript:

class Dog {
  constructor(name, age) {
    this.name = name
    this.age = age
  }

  barkHello() {
    console.log(`Woof! I am called ${this.name} and I am ${this.age} human-years old.`)
  }
}

The Dog class is a collection of variables and methods. The constructor method is a special method JavaScript executes when a new dog is created. We will talk about this shortly. The variables in this class are this.name and this.age. The method in this class is barkHello.

Instantiating objects from classes

By defining the dog class we now know the structure that each of our dogs will have. It's like we have made a new variable type! But how do we make new dogs, or new variables of this type? We call our class name as a function with the new keyword:

const gracie = new Dog('Gracie', 8);

This will create a new object according to our Dog class specification. When that happens, JavaScript runs our constructor method. Our constructor method sets the name of this dog to 'Gracie' and sets her age to 8 years old.

So, what's this this keyword? When we make objects from this class, the this keyword inside each object refers to that specific object. This allows each object made from a class to maintain its own copies of variables.

this can be a strange programming paradigm. Imagine that you are an object. You represent the this. If you wanted to access your arm, it would be this.arm. Your name would probably be stored in this.name. This lets each object made from a class keep reference to its own data and function members. Not every 'Person' has the same name so we want individual People to maintain their own names. The this keyword is each objects' identity.

Let's make a couple more dogs so we can see the differences in our dog objects:

const spitz = new Dog('Spitz', 5);  // lead dog
const buck = new Dog('Buck', 3);    // upstart newcomer

Each dog has its own name and age. Let's have them say hello:

gracie.barkHello();  // Woof! I am called Gracie and I am 8 human-years old.'
spitz.barkHello();   // Woof! I am called Spitz and I am 5 human-years old.'
buck.barkHello();    // Woof! I am called Buck and I am 3 human-years old.'

Let's add some more code to better see what is going on behind the scenes.

Class (static) vs Instance members

In our Dog class, we have variables attached to the this property that exist independently for each object that's created. These are called instance variables. Each object instance has its own copies of these variables and they can vary across objects. We can also attach variables to the class itself so that there's one single thing that exists for an entire class. These go by different names in different languages but in JavaScript are called static variables.

Suppose we want to keep a tally of how many dogs we have running around in our app. We could put a copy of the tally in each dog object but that's not efficient: we would be duplicating a value in memory multiple times and we would have to update the value in every dog object in order to keep it accurate. It's much better if we can store it once in the class. That way, each dog object can access it but we only need to store it and set it in one place.

There is a nice, clean way to do this but we must use a very new feature called "class fields syntax" which simplifies the adding of member variables to a class as well as giving us the ability to easily add static variables. This is an experimental feature and is not supported in all browsers as of 2019 but when we develop using React (or any build chain that involves the Babel transpiler) we can have our newer-syntax JavaScript "transpiled" into older JavaScript that does run in older browsers.

Let's update our class to add a totalDogs variable to the class. Let's also add a line that increments this value inside our constructor method. And just for fun, let's add another line to our barkHello method that references this total:

class Dog {
  static totalDogs = 0;

  constructor(name, age) {
    this.name = name;
    this.age = age;
    Dog.totalDogs++;
  }

  barkHello() {
    console.log(`Woof! I am called ${this.name} and I am ${this.age} human-years old.`);
    console.log(`There are ${Dog.totalDogs} dogs in this room!`);
  }
}

Now when we create a new dog, the constructor method increments the totalDogs counter which is stored in the Dog class itself. We can access the value stored in Dog.totalDogs inside our script and each dog object can access it from their own functions.

Inheritance

Another amazing feature of classes and one of the central aspects of Object Oriented Programming is the idea of having one class inherit functionality and basic structure from another class. Using this idea, you can organize your classes from general to specific where "child" classes that inherit functionality from "parent" classes can refine and extend that parent's behaviors.

For example, we have a Dog class and all dogs bark but not all dogs can fetch. We could add this functionality to the base Dog class but since not all dogs fetch this doesn't make good design sense. What we should do is use the Dog class as our parent or super class and then create a child or sub class that has this more specific behavior. Let's make a Retriever class:

class Retriever extends Dog {
  constructor(name, age) {
    super();
  }

  fetch() {
    console.log(`Woof! Here is the ball you just threw.`);
  }
}

The extends keyword is the special syntax here. We say that Retriever extends Dog and this tells JavaScript that any object made from the Retriever class will also have all the data and behavior from the Dog class. There is also a new function in our constructor. Calling super() invokes the constructor from the parent but does all of its operations for the new object we are instantiating. Let's try it out:

const boots = new Retriever('Boots', 5);  // good girl
const miriya = new Dog('Miriya', 10);     // Zentraedi airforce leader

boots.barkHello();  // Woof! I am called Boots and I am 5 human-years old.'
boots.fetch();      // Woof! Here is the ball you just threw.
miriya.fetch();     // ERROR, the Dog class doesn't have a fetch method

So we can see that the subclass dog, an instance of the Retriever class, has not only the new fetch() method but also the barkHello() method from the Dog class. But notice that any object instantiated from the Dog class does NOT have the fetch() method. That is because inheritance only works downward. Superclasses pass members down to subclasses, not the other way around.

Principles of Object Oriented Programming

There are three main aspects of OOP that people cite as the main advantages. Sometimes this question comes up in interviews so now that we have seen the machanics of OOP in JavaScript let's see how they make up the paradigm of OOP:

Encapsulation

That is a big, fancy word that means that your data and functions inside a class are protected and scoped to that class. Each object encapsulates its own data attributes and functions and because they are inside of an object, they are protected from global variable accesses. It also adds the benefit of organization because a class only needs to contain things relevant to the class itself. Classes are generally self-contained, modular and reusable - which are all good things in programming.

When we add a static variable to a class that can only be accessed through that class, that is a perfect example of the benefit of encapsulation. When we attach the data that comes in via the constructor to the individual objects we instantiate, that is also one of the virtues of encapsulation.

Inheritance

As we showed above, classes can incorporate behavior from other classes by inheriting from them using the extends keyword. This leads to a lot of code savings. If we need more specific or additional functionality in a class we can simply extend that class and not need to rewrite anything. Most large software solutions, including Node and the DOM built into the browser, are built as a big collection of general-to-specific classes.

Polymorphism

A term meaning "many shapes", polymorphism refers to the ability of a function or even a whole object to take on different behaviors depending on which class is being called. Though the name of a function can stay the same as it is inherited to other classes, those subclasses can override that function with new or extended behavior. The code calling that method calls it the same as it would any other time but it will do different things depending on what object it was called on, hence "many shapes".

Exercise: Create Your Own JavaScript Class

Now that we've seen a dog-based example of JavaScript classes, let's make one a bit more sophisticated. Create a BankAccount class.

  • Bank accounts should be created with the accountType property (like "savings" or "checking").

  • Bank accounts should have a class-level (static) variable tracking the total amount of money in all accounts.

  • Each account should keep track of it's current balance.

  • Each account should have access to a deposit and a withdraw method.

  • Each account should start with a balance set to zero.

Things to think about:

  • Any starting values for variables should be set in the constructor method

  • Static variables are declared using the static keyword inside the class but outside any methods

  • Instance variables are declared inside the constructor method

  • Does your constructor method need to accept any parameters?

Bonus: Start each account with an additional overdraftFees property that starts at zero. If a call to withdraw ends with the balance below zero then overdraftFees should be incremented by twenty.

Bonus bonus: Create a ChildBankAccount class that overrides the withdraw method to eliminate the overdraft penalty fee and simply disallow the withdrawal if there aren't enough funds.

Closing Thoughts

  • A Class is a pre-defined structure that contains attributes and methods that are grouped together logically.

  • An Object is an instance of a Class structure. A class could be thought of as a house blueprint and an object as a house built from the blueprint.

  • Classes are defined via a method call. Classes contain an constructor method that takes in parameters to be assigned to member variables (properties) of an Object.

  • Instance variables contain data types declared in the class but defined in each object.

  • Static variables and methods contain data and actions that live on the class itself.

  • The this keyword lets us distinguish between variables that exist in different objects and refer to the object we are currently in.

PreviousHow To Reduce RedundancyNext(2016) OOP with Classes

Last updated 3 years ago

Was this helpful?