Giter Club home page Giter Club logo

u1_lesson_oop's Introduction

Object-Oriented Javascript

Image Header

Overview

Object-oriented programming (OOP) is a programming paradigm based on the concept of objects, which contain data, in the form of fields, often known as properties and functions often known as methods. When you define a class, you define a blueprint for an object. This doesn't actually define any data, but it does define what the class name means, that is, what an object of the class will consist of and what operations can be performed on such an object. In this lesson, we'll be covering how to implement OOP with JavaScript.

Getting Started

  • Fork and Clone
  • Create an index.js file

Objectives

  • Use the new keyword to create objects with shared properties and methods
  • Describe the role of classes in JavaScript
  • Explain the importance of Object-Oriented Programming
  • Define the concept of inheritance as it pertains to classes
  • Create a class that inherits from another using the extends and super keywords

What is an object in programming?

An object encapsulates related data and behavior in an organized structure.

We've already gotten exposure to Javascript objects using object literal notation. We could define a car object in this way:

const car = {
  make: 'Honda',
  model: 'Civic',
  color: 'red',
  drive() {
    console.log('vroom vroom');
  },
  gps(location) {
    console.log(`Beep boop, driving to ${location}`);
  },
  paint(newColor) {
    console.log(`Your car has been painted ${newColor}`);
    this.color = newColor;
  },
};

What's nice about the above code snippet?

Some thoughts...
  • Related properties and methods are packaged together.
  • Fewer global variables.
  • Readability.

Why might we use an OOP approach to programming?

Object-oriented programming (OOP) provides us with opportunities to clean up our procedural code and model it more-closely to the external world.

OOP helps us to achieve the following...

  • Abstraction: hiding all but the relevant data about an object in order to reduce complexity and increase efficiency
  • Encapsulation: is the process of combining data and functions into a single unit
  • Inheritance: Enables new objects to receive or inherit the properties and methods of existing objects
  • Polymorphism: Allows for many forms of the same type of object through inheritance

OOP becomes very important as our front-end code grows in complexity. Even a simple app will have lots of code on the front-end to do things like...

  • Send requests to a back-end to fetch / update / destroy data
  • Update the state of the page as data changes
  • Respond to events like clicking buttons

Creating Objects

Assembly

So far, we've had to make our objects 'by hand' (i.e. using object literals)...

const celica = {
  model: 'Toyota Celica',
  color: 'limegreen',
  fuel:  100,
  drive() {
    this.fuel--;
    return 'Vroom!';
  },
  refuel() {
    this.fuel = 100;
  },
};

const civic = {
  model: 'Honda Civic',
  color: 'lemonchiffon',
  fuel:  100,
  drive() {
    this.fuel--;
    return 'Vroom!';
  },
  refuel() {
    this.fuel = 100;
  },
};

Even though we're technically using objects to organize our code, we can see a noticeable amount of duplication. Just imagine if we needed a hundred cars in our app! Our code would certainly not be considered "DRY".

As you may have noticed, some of these properties change between cars, and others stay the same. In the example above, while the model and color properties may vary, the fuel property and drive and refuel functions are the same for every car.

Making all of these similar objects by hand is just tedious. What if we could build a function that makes them for us?

Create a makeCar Function

Define a function makeCar that takes two parameters - model and color - and returns an object literal representing a car using those params.

// This should return a car object just like the previous example
const celica = makeCar('Toyota Celica', 'limegreen');
Solution...
const makeCar = function(model, color){
  return {
    model: model,
    color: color,
    fuel:  100,
    drive: function() {
      this.fuel--;
      return 'Vroom!';
    },
    refuel: function() {
      this.fuel = 100;
    }
  }
}

This is the basic idea behind OOP; we define a blueprint for an object and use it to generate multiple instances of it!

Car Class Blueprint

Classes

It's so common that we need to make objects with similar properties and methods that programming languages usually have some features to help with this.

In Javascript, ES6 added a feature called classes to accomplish this. A class serves as a blueprint for instantiating new objects.

Let's take a look the following Car class:

class Car {
  constructor(model, color) {
    this.model = model;
    this.color = color;
    this.fuel = 100;
  }
  drive() {
    this.fuel--;
    return 'Vroom!';
  }
  refuel() {
    this.fuel = 100;
  }
}


const celica = new Car('Toy-Yoda Celica', 'limegreen');
const civic = new Car('Honda Civic', 'lemonchiffon');

Classes work a lot like the makeCar function we just created, but are a more performant and offer more robust features.
We use the new keyword to generate instances of a class (just like our earlier celica and civic examples).

Note that classes typically are capital case to make it obvious that they are classes. This isn't necessary, but is a convention you should follow.

Make a Person Class

class Person {
  // We use the constructor method to initialize properties for a class instance.
  // It takes whatever arguments we want to pass into an instance.
  constructor(initialName) {
    this.name = initialName;
    this.species = 'Homo Sapiens';
  }
  // We define any methods accessible to an instance outside of the constructor
  speak(){
    return `Hello! Iā€™m ${this.name}`;
  }
}

const andy = new Person('Andy');
andy.speak(); // "Hello, I'm Andy"

this

this

Notice the use of this, and the fact that we don't return from the class. Here's why we write classes this way...

When we generate a class instance using new, Javascript will automatically...

  1. Create a new, empty object for us
  2. Generate a context for that object (this -> the new object)
  3. Return the object

Where are the Commas?

Unlike object notation, you do not need to use commas when separating class methods.

Inheritance

Although OOP can help us keep our Javascript nice and clean, it's still easy to duplicate code when defining multiple classes. Consider the following example...

class Dog {
  constructor(name, breed, tail) {
    this.name = name;
    this.breed = breed;
    this.waggingTail = tail;
    this.diet = [];
  }
  eat(food) {
    this.diet.push(food);
    console.log(this.diet);
  }
  bark() {
    return `Bark! Hello, this is dog. My name is ${this.name}`;
  }
}

class Cat {
  constructor(name, breed, numLives) {
    this.name = name;
    this.breed = breed;
    this.numLives = numLives;
    this.diet = [];
  }
  eat(food) {
    this.diet.push(food);
    console.log(this.diet);
  }
  meow() {
    return `Meow! I am not a dog! My name is ${this.name}`
  }
}

Here we have two classes: Dog and Cat. They have some things in common: name, breed, diet and eat. They do differ, however, in that one barks and the other meows.

Imagine that we had to create a number of other classes - Horse, Goat, Pig, etc. - all of which share the same aforementioned properties but also have methods that are particular to the class.

How could we refactor this so that we don't have to keep writing out the shared class properties and methods. Enter inheritance

class Animal{
  constructor(name, breed) {
    this.name = name;
    this.breed = breed;
    this.diet = [];
  }
  eat(food) {
    this.diet.push(food);
    console.log(this.diet);
  }
}

const dog = new Animal('Fido', 'Beagle');

Here we've defined an Animal class. It contains the properties and methods that are common among specific animal classes. Wouldn't it be nice if Dog and Cat could just reference this "parent" Animal class so that the only things we need to put in their "child" class definitions are the properties and methods that are particular to them (e.g., bark, meow).

Lucky for us, we can do that...

class Animal {
  constructor(name, breed){
    this.name = name;
    this.breed = breed;
    this.diet = [];
  }
  eat(food){
    this.diet.push(food);
    console.log(this.diet);
  }
}

class Dog extends Animal {
  constructor(name, breed, tail){
    this.waggingTail = tail;
  }
  bark(){
    return `Bark! Hello, this is dog. My name is ${this.name}`
  }
}

class Cat extends Animal {
  constructor(name, breed, numLives){
    this.numLives = numLives;
  }
  meow(){
    return `Meow! I am not a dog! My name is ${this.name}`
  }
}

The clincher is extends. Whatever class is to the left of the extends keyword should inherit the properties and methods that belongs to the class to the right of the keyword. Let's see if this works...

// Let's test out our parent. It just needs a name and breed.
const goat = new Animal("Gregory", "Mountain Goat");

// And now the children.
const fido = new Dog('Fido', 'Beagle', true);
console.log(fido); // "this is not defined"

That didn't work out the way we expected. That's because we're forgetting one thing. When creating an instance of a child class, we need to make sure it invokes the constructor of the parent (Animal) class.

We can do that using the keyword super()

class Dog extends Animal {
  constructor(name, breed, tail){
    super(name, breed);
    this.waggingTail = tail;
  }
  bark(){
    return `Bark! Hello, this is dog. My name is ${this.name}`
  }
}

super() calls the constructor of the parent class. In the above example, once super does what it needs to do, it then runs through the rest of Dogs constructor.

  • In order to give an instance of a child class context (i.e., be able to use this), you must call super.

  • If the keyword super is confusing, think of a supervisor to understand that we're calling out to the next level above us (to the parent class's constructor).

Recap

In JavaScript Object Oriented Programming we use classes to create reusable data models for objects. Classes use constructor() methods to take in data for a new object created by the class. Classes can also be inherited by extending another pre-defined class and calling the parent class's constructor with the super() method. A few JavaScript key words worth noting with OOP:

  • class - defines a new class (reusable object model) Ex: class Dog { //methods and properties here }
  • constructor() - primary method for instantiating the properties of a class
  • this - creates context for object to refer to itself from within its methods
  • new - used to create a new instance of a class. Ex: const lab = new Dog()
  • extends - used to inherit the methods and properties of an existing class when defining a new class
  • super() - method for calling to a parent class's constructor, inheriting it's arguments and properties

Resources

Prototypical Inheritance

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    šŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. šŸ“ŠšŸ“ˆšŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ā¤ļø Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.