Skip to content

Instantly share code, notes, and snippets.

@vxhviet
Last active August 7, 2023 12:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vxhviet/024720f8bf3176af3934c23d345b0b89 to your computer and use it in GitHub Desktop.
Save vxhviet/024720f8bf3176af3934c23d345b0b89 to your computer and use it in GitHub Desktop.

[JavaScript] - Inheritance Between Classes

Constructor Function

const Person = function (firstName, birthYear) {
  this.firstName = firstName;
  this.birthYear = birthYear;
};

Person.prototype.calcAge = function () {
  console.log(2037 - this.birthYear);
};

const Student = function (firstName, birthYear, course) {
  // Person(firstName, birthYear); // error, this doesn't work as expected as without the `new` operator, this is just a function call and `this` inside a function call is set to undefined
  Person.call(this, firstName, birthYear); // use this to manually set `this` as well
  this.course = course;
};

// Linking prototypes
//Student.prototype = Person.prototype // this is wrong as this this is basically the equivalence of saying these two objects are the same while we are trying to link the Student prototype to Person prototype
Student.prototype = Object.create(Person.prototype); // do this

Student.prototype.introduce = function () {
  console.log(`My name is ${this.firstName} and I study ${this.course}`);
};

const mike = new Student('Mike', 2020, 'Computer Science');
mike.introduce();
mike.calcAge();

console.log(mike.__proto__);
console.log(mike.__proto__.__proto__);

console.log(mike instanceof Student); // true
console.log(mike instanceof Person); // true
console.log(mike instanceof Object); // true

console.dir(Student.prototype.constructor); // this should point to Student but it instead points to Person
Student.prototype.constructor = Student; // fix it with this
console.dir(Student.prototype.constructor); // it correctly point to Student now

ES6 Classes

Basically the above but in a more convenient syntax.

class PersonCl {
  constructor(fullName, birthYear) {
    this.fullName = fullName;
    this.birthYear = birthYear;
  }

  // Instance methods
  calcAge() {
    console.log(2037 - this.birthYear);
  }

  greet() {
    console.log(`Hey ${this.fullName}`);
  }

  get age() {
    return 2037 - this.birthYear;
  }

  set fullName(name) {
    if (name.includes(' ')) this._fullName = name;
    else alert(`${name} is not a full name!`);
  }

  get fullName() {
    return this._fullName;
  }

  // Static method
  static hey() {
    console.log('Hey there 👋');
  }
}

class StudentCl extends PersonCl {
  constructor(fullName, birthYear, course) {
    // Always needs to happen first!
    super(fullName, birthYear);
    this.course = course;
  }

  introduce() {
    console.log(`My name is ${this.fullName} and I study ${this.course}`);
  }

  calcAge() {
    console.log(
      `I'm ${
        2037 - this.birthYear
      } years old, but as a student I feel more like ${
        2037 - this.birthYear + 10
      }`
    );
  }
}

const martha = new StudentCl('Martha Jones', 2012, 'Computer Science');
martha.introduce();
martha.calcAge();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment