skip to Main Content

seems a confusing concept of having prototype to create methods to a class as below. why can’t we simply avoid using prototypes and all like other OOP languages

class Person {
    constructor(firstName, lastName, age, dobYear) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
        this.dobYear = dobYear;
    }
    calcPresentAge() {
        console.log(this.dobYear + this.age);
    }
}

Person.prototype.callName = function () {
    console.log(`${this.firstName} ${this.lastName}`);
};

//why can't we use Person.callName = function(){console.log(`${this.firstName} ${this.lastName}`);}

const person1 = new Person("Jessica", "Jones", 29, 1991);
console.log(person1.callName());

2

Answers


  1. It’s better to know how JS classes were added to the language. OOP is a concept, and how it is implemented in JS is using function prototypes.

    Consider following JS code in ES6

    class Animal {
      constructor(name) {
        this.name = name;
      }
    
      speak() {
        console.log(`${this.name} makes a noise.`);
      }
    }
    
    class Dog extends Animal {
      constructor(name) {
        super(name); // call the super class constructor and pass in the name parameter
      }
    
      speak() {
        console.log(`${this.name} barks.`);
      }
    }
    
    const d = new Dog("Mitzie");
    d.speak(); // Mitzie barks.

    When the same code is transpiled into ES5 which didn’t have class and extends keywords it will look like below:

    function Animal(name) {
      this.name = name;
    }
    
    Animal.prototype.speak = function () {
      console.log(this.name + " makes a noise.");
    };
    
    // Transpiled version of the Dog class
    function Dog(name) {
      Animal.call(this, name); // call the super class constructor and pass in the name parameter
    }
    
    Dog.prototype = Object.create(Animal.prototype);
    Dog.prototype.constructor = Dog;
    
    Dog.prototype.speak = function () {
      console.log(this.name + " barks.");
    };
    
    const d = new Dog("Mitzie");
    d.speak(); // Mitzie barks.

    If you are familiar with OOP in a Java-like language, then you don’t need to bother about prototype functions and prototype chaining. You can use the class and extends (for inheritance) abstractions and it’s just like Java classes.

    There is a book called "You Don’t Know JS: this & Object Prototypes" by @Kyle Simpson, it will clear your doubts for sure.

    Login or Signup to reply.
  2. … because Javascript is not class based, it is prototype based. I.E. inheritance is via Object.prototype property, not a class. So why does JS have a class keyword?

    The Class keyword was introduced in ES6 in 2015. It is "syntactic sugar" allowing you to code in a way that is familiar in classed-based languages such as Java & C#. Under the hood JS is doing what it has always done.

    Sure it’s a technical point but given that JS is a dynamic language prototype-based enables run-time, that is dynamic, object & inheritance chain modification.

    It has always been said that "JS is object based not object oriented." But one might argue that JS is more so object oriented because there is no such thing as a class.

    To be clear: Javascript has not implemented classes in the language.


    //why can’t we use

    Person.callName = function(){console.log(`${this.firstName} ${this.lastName}`);}
    

    You can but it is not inherited by new Persons. Stuff like this is just the tip of the confusion iceberg of this, inheritance, scope, private vs. public methods; a hint of the motivation for creating pretend class syntax.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search