Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Building Data-Driven Applications with Danfo.js

You're reading from   Building Data-Driven Applications with Danfo.js A practical guide to data analysis and machine learning using JavaScript

Arrow left icon
Product type Paperback
Published in Sep 2021
Publisher Packt
ISBN-13 9781801070850
Length 476 pages
Edition 1st Edition
Languages
Arrow right icon
Authors (2):
Arrow left icon
Stephen Oni Stephen Oni
Author Profile Icon Stephen Oni
Stephen Oni
Rising Odegua Rising Odegua
Author Profile Icon Rising Odegua
Rising Odegua
Arrow right icon
View More author details
Toc

Table of Contents (18) Chapters Close

Preface 1. Section 1: The Basics
2. Chapter 1: An Overview of Modern JavaScript FREE CHAPTER 3. Section 2: Data Analysis and Manipulation with Danfo.js and Dnotebook
4. Chapter 2: Dnotebook - An Interactive Computing Environment for JavaScript 5. Chapter 3: Getting Started with Danfo.js 6. Chapter 4: Data Analysis, Wrangling, and Transformation 7. Chapter 5: Data Visualization with Plotly.js 8. Chapter 6: Data Visualization with Danfo.js 9. Chapter 7: Data Aggregation and Group Operations 10. Section 3: Building Data-Driven Applications
11. Chapter 8: Creating a No-Code Data Analysis/Handling System 12. Chapter 9: Basics of Machine Learning 13. Chapter 10: Introduction to TensorFlow.js 14. Chapter 11: Building a Recommendation System with Danfo.js and TensorFlow.js 15. Chapter 12: Building a Twitter Analysis Dashboard 16. Chapter 13: Appendix: Essential JavaScript Concepts 17. Other Books You May Enjoy

Object-oriented programming and JavaScript classes

OOP is a common programming paradigm supported by most high-level languages. In OOP, you typically program an application using the concept of objects, which can be a combination of data and code.

Data represents information about the object, while code represents attributes, properties, and behaviors that can be carried out on objects.

OOP opens up a whole new world of possibilities as many problems can be simulated or designed as the interaction between different objects, thereby making it easier to design complex programs, as well as maintain and scale them.

JavaScript, like other high-level languages, provides support for OOP concepts, although not fully (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes), but in essence, most of the important concepts of OOP, such as objects, classes, and inheritance, are supported, and these are mostly enough to solve many problems you wish to model using OOP. In the following section, we will briefly look at classes and how these are related to OOP in JavaScript.

Classes

Classes in OOP act like a blueprint for an object. That is, they define a template of an abstract object in such a way that multiple copies can be made by following that blueprint. Copies here are officially called instances. So, in essence, if we define a class, then we can easily create multiple instances of that class.

In ECMA 2015, the class keyword was introduced to JavaScript, and this greatly simplified the creation of classes in the language. The following code snippet shows how to model a User object using the ES16 class keyword:

class User {
    constructor(firstName, lastName, email) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }
    getFirstName() {
        return this.firstName;
    }
    getLastName() {
        return this.lastName;
    }
    getFullName() {
        return `${this.firstName} ${this.lastName}`;
    }
    getEmail() {
        return this.email;
    }
    setEmail(email) {
        this.email = email;
    }
}
let Person1 = new User("John", "Benjamin", "john@some-email.com")
console.log(Person1.getFullName());
console.log(Person1.getEmail());
// outputs 
// "John Benjamin"
// "john@someemail.com"

By using the class keyword, you can wrap both data (names and email) with functionality (functions/methods) in a cleaner way that aids easy maintenance as well as understanding.

Before we move on, let's break down the class template in more detail for a better understanding.

The first line starts with the class keyword and is usually followed by a class name. A class name, by convention, is written in camel case, for instance, UserModel or DatabaseModel.

An optional constructor can be added inside a class definition. A constructor class is an initialization function that runs every time a new instance is created from a class. Here, you'll normally add code that initializes each instance with specific properties. For instance, in the following code snippet, we create two instances from the User class, and initialize them with specific properties:

let Person2 = new User("John", "Benjamin", "john@some-email.com")
let Person3 = new User("Hannah", "Joe", "hannah@some-email.com")
console.log(Person2.getFullName());
console.log(Person3.getFullName());
//outputs 
// "John Benjamin"
// "Hannah Montanna"

The next important part of a class is the addition of functions. Functions act as class methods and generally add a specific behavior to the class. Functions are also available to every instance created from the class. In our User class, methods such as getFirstName, getLastName, getEmail, and setEmail are added to perform different functions based on their implementation. To call functions on class instances, you typically use a dot notation, as you would when accessing an object's property. For example, in the following code, we return the full name of the Person1 instance:

Person1.getFullName()

With classes out of the way, we now move to the next concept in OOP, called inheritance.

Inheritance

Inheritance in OOP is the ability of one class to use properties/methods of another class. It is an easy way of extending the characteristics of one class (subclass/child class) using another class (superclass/parent class). In that way, the child class inherits all the characteristics of the parent class and can either extend or change these properties. Let's use an example to better understand this concept.

In our application, let's assume we already have the User class defined in the previous section, but we want to create a new set of users called Teachers. Teachers are also a class of users, and they will also require basic properties, such as the name and email that the User class already has. So, instead of creating a new class with these existing properties and methods, we can simply extend it, as shown in the following code snippet:

class Teacher extends User {
}

Note that we use the extends keyword. This keyword simply makes all the properties in the parent class (User) available to the child class (Teacher). With just the basic setup, the Teacher class automatically has access to all the properties and methods of the User class. For instance, we can instantiate and create a new Teacher in the same way we created a User value:

let teacher1 = new Teacher("John", "Benjamin", "john@someemail.com")
console.log(teacher1.getFullName());
//outputs
// "John Benjamin"

After extending a class, we basically want to add new features. We can do this by simply adding new functions or properties inside the child class template, as shown in the following code:

class Teacher extends User {
  getUserType(){
    return "Teacher"
  }
}

In the preceding code snippet, we added a new method, getUserType, which returns a string of the user type. In this way, we can add more features that were not originally in the parent class.

It is worth mentioning that you can replace parent functions in the child class by creating a new function in the child class with the same name. This process is called method overriding. For instance, to override the getFullName function in the Teacher class, we can do the following:

class User {
    constructor(firstName, lastName, email) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }
    getFirstName() {
        return this.firstName;
    }
    getLastName() {
        return this.lastName;
    }
    getFullName() {
        return `${this.firstName} ${this.lastName}`;
    }
    getEmail() {
        return this.email;
    }
    setEmail(email) {
        this.email = email;
    }
}
class Teacher extends User { 
    getFullName(){ 
      return `Teacher: ${this.firstName} ${this.lastName}`; 
    } 
    getUserType(){ 
      return "Teacher" 
    } 
  } 
let teacher1 = new Teacher("John", "Benjamin", "john@someemail.com") 
console.log(teacher1.getFullName()); 
//output 
// "Teacher: John Benjamin"

A question may arise here: What if we want to initialize the Teacher class with additional instances besides firstname, lastname, and email? This is achievable, and we can easily extend the constructor function by using a new keyword, super. We demonstrate how to do this in the following code:

// class User{
// previous User class goes here
//     ... 
// }
 
class Teacher extends User {
    constructor(firstName, lastName, email, userType, subject) {
        super(firstName, lastName, email) //calls parent class constructor 
        this.userType = userType
        this.subject = subject
    }
    getFullName() {
        return `Teacher: ${this.firstName} ${this.lastName}`;
    }
    getUserType() {
        return "Teacher"
    }
}
let teacher1 = new Teacher("Johnny", "Benjamin", "john@someemail.com", "Teacher", "Mathematics")
console.log(teacher1.getFullName());
console.log(teacher1.userType);
console.log(teacher1.subject);
//outputs 
// "Teacher: Johnny Benjamin"
// "Teacher"
// "Mathematics"

In the preceding code, we are performing two new things. First, we add two new instance properties (userType and subject) to the Teacher class, and then we are calling the super function. The super function simply calls the parent class (User), and performs the instantiation, and immediately after, we initialize the new properties of the Teacher class.

In this way, we are able to first initialize the parent properties before initializing the class properties.

Classes are very useful in OOP and the class keyword provided in JavaScript makes working with OOP easy. It is worth mentioning that under the hood, JavaScript converts the classes template to an object, as it does not have first-class support for classes. This is because JavaScript, by default, is a prototype-based, object-oriented language. Hence, the class interface provided is called syntactic sugar over the underlying prototype-based model, which JavaScript calls under the hood. You can read more about this at the following link: http://es6-features.org/#ClassDefinition.

Now that we have a basic understanding of OOP in JavaScript, we are ready to create complex applications that can be easily maintained. In the next section, we will discuss another important aspect of JavaScript development, which is setting up a development environment with modern JavaScript support.

You have been reading a chapter from
Building Data-Driven Applications with Danfo.js
Published in: Sep 2021
Publisher: Packt
ISBN-13: 9781801070850
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €18.99/month. Cancel anytime