Prototypes and Inheritance

Prototypes and Inheritance

What do you mean by programming paradigms?

  • Any coding language has different levels of support for writing/using structures like functions, objects etc.
  • Based on how a language is created and how it has evolved over time, what the language supports more defines in which programming paradigm the language falls.
  • For example: Java, C++, C#, Python, Dart are languages that have great support and structure for Objects and Classes. That's why they are referred as Object Oriented languages.
  • Similarly languages like Lisp, Haskell, Clojure, Erlang, Elixir have better support and structure for Functions. That's why they are referred as Functional Programming languages.
  • There are many different programming paradigms, the few most popular ones are:
    - Object Oriented,
    - Functional
    - Imperative,
    - Procedural

     

Prototypes and Inheritance

Object Oriented Programming:

  • Object-oriented programming (OOP) is a programming paradigm based on the concept of objects,
  • Objects can contain data and code:
  • data in the form of fields (often known as attributes or properties),
  • code in the form of functions (often known as methods).
  • In OOP, computer programs are designed by making them out of objects that interact with one another.

Object Oriented Programming:

When you're writing code using objects heavily, it's k/a object oriented programming.

Object Oriented Language:

A Language that has better support for using Objects and classes

Prototypes and Inheritance

Object Oriented Programming:

  • We are to understand OOP, that means how to write code leveraging objects and classes and all their features.
  • So that we can write object oriented code in any language.
  • How to write object oriented code?

The 4 pillars of Object Oriented Programming:

  • Abstraction - abstract away the implementation logic

  • Encapsulation - hiding/protecting the data (private properties)

  • Inheritance - access properties of some other object in your object

  • Polymorphism - a method giving different output in one object and different in another

Prototypes and Inheritance

SOLID Principles:

  • S - Single-responsibility Principle
  • O - Open-closed Principle
  • L - Liskov Substitution Principle
  • I - Interface Segregation Principle
  • D - Dependency Inversion Principle

Prototypes and Inheritance

Difference between OOP in JavaScript and other OOP based languages like Java, C++ etc:

  • Classical Inheritance: All OO languages create new objects using classes. These objects inherit methods and properties through classical way of inheritance i.e, by being the instance of their parent class.
  • Prototypal Inheritance: But in JavaScript, there's no such thing as a class. JavaScript uses constructor functions to create new objects. Thus for inheriting methods and properties, it relies on a property called "prototype". This property exists on all the objects. Its value is either an object or null.
class SomeClass {
  constructor(name){
    this.name = name
  }
  method1(){}
  
  method2(){}
}

const someClassObject1 = new SomeClass()
const someClassObject2 = new SomeClass()
const someClassObject3 = new SomeClass()


const protoObj = {
	name: "yash",

	method1: function(){},

	method2: function(){}
}
const myObj = {
   __proto__: protoObj
}

Prototypes and Inheritance

What are Prototypes?

Let's say you have an object with a few properties and methods:

const baseStudent = {
  college: "College Name",
  city: "Bhopal",

  getStudentFullName: () => {
    return `${this.firstName} ${this.lastName}`
  },

  getStudentBranch: () => {
    return this.branchName
  }
}

Prototypes and Inheritance

What are Prototypes?

Now you have a completely different object `student1` where you want to leverage the properties of the `baseStudent` object

const baseStudent = {
  college: "College Name",
  city: "Bhopal",

  getStudentFullName: () => {
    return `${this.firstName} ${this.lastName}`
  },

  getStudentBranch: () => {
    return this.branchName
  }
}

baseStudent.getStudentFullName() // 
baseStudent.getStudentBranch()


const student1 = {
  firstName: "Yash",
  lastName: "Priyam"
}

student1.getStudentFullName() // not a function
student1.getStudentBranch() // not a function

Prototypes and Inheritance

What are Prototypes?

  • You can add properties of one object to another object by making baseStudent the prototype of student1,
  • all the properties (data and methods) of baseStudent are now inherited by student1 object,
  • A Prototype is an object having some methods and data properties in it,
  • To access those on any other object, you can make it as other object's prototype.
  • There are 2 syntaxes for adding prototypes:
const baseStudent = {
  college: "College Name",
  city: "Bhopal",

  getStudentFullName: () => {
    return `${this.firstName} ${this.lastName}`
  },

  getStudentCollegeCity: () => {
    return this.city
  }
}

// Method 1
const student1 = {
  firstName: "Yash",
  lastName: "Priyam",
  __proto__: baseStudent
}

// Method 2
student1.__proto__ = baseStudent

student1.getStudentFullName() // "Yash Priyam"
student1.getStudentCollegeCity() // "Bhopal"

Prototypes and Inheritance

[[Prototype]]:

  • Every object has a special property on it named: [[Prototype]],
  • __proto__ is just a getter/setter for [[Prototype]], that means it can only get or set the [[Prototype]] property,
  • __proto__ is not the same as the internal [[Prototype]] property.
const baseStudent = {
  college: "College Name",
  city: "Bhopal",

  getStudentFullName: () => {
    return `${this.firstName} ${this.lastName}`
  },

  getStudentCollegeCity: () => {
    return this.city
  }
}

// Method 1
const student1 = {
  firstName: "Yash",
  lastName: "Priyam",
  __proto__: baseStudent
}

// Method 2
student1.__proto__ = baseStudent

student1.getStudentFullName() // "Yash Priyam"
student1.getStudentCollegeCity() // "Bhopal"

JavaScript is a prototype-based language, meaning every "object" data type has an internal property [[Prototype]].

Prototypes and Inheritance

"prototype":

  • The already existing data structures like array, objects, map, sets, class etc have a property named "prototype",
  • You can directly use this property to add methods/properties to the prototype of the data structure, but
  • You can only use this property directly on in-built data structures,
  • Once you have added a property, all the structures you create using that will have access to that property,
  • Not a very good practice though
Array.prototype.myMap = function(){}
Object.prototype
String.prototype
Number.prototype
Map.prototype


/**
the property "prototype" is 
available only directly on 
the built-in data types
*/
const arr = new Array()
arr.prototype // undefined

Prototypes and Inheritance

Prototype Chain:

  • For multi-level inheritance,
  • When your prototype object itself has a prototype, and so on
  • A prototype chain represents prototypes connected top down,
  • If you follow any prototype chain, you will reach to an object which has it's prototype as null
const baseObj = {
  zero: 0
}

const obj1 = {
  one: 1,
  __proto__: baseObj
}

const obj2 = {
  two: 2,
  __proto__: obj1
}

const obj3 = {
  three: 3,
  __proto__: obj2
}

console.log({obj3})

Prototypes and Inheritance

null prototype object:

  • you can set an object's prototype to null,
  • then you won't be able to access object methods on your object,
  • when you set the prototype as null, it marks the end of prototype chain
const baseObj = {
  zero: 0
}

const obj1 = {
  one: 1,
  __proto__: baseObj
}

const obj2 = {
  two: 2,
  __proto__: obj1
}

const obj3 = {
  three: 3,
  __proto__: obj2
}

console.log({obj3})

Prototypes in JavaScript

By Yash Priyam

Prototypes in JavaScript

  • 95