0

I'm studying JavaScript autodidactically, I was searching for ways to inherit from objects and extend their functionalities as well...and... wow! it turns out there are several ways to do it.

So there is a popular one which is extending an object through extend and class keywords (to say it in short) of which I put an example of what I saw right underneath. Ok, since I come from C++ and Python languages, this is indeed! very helpful... but I'm aware of this is sugar code to help programmers who come from object-oriented languages feel JavaScript cozier. So!, my goal is to know how to extend objects functionalities without using the aforementioned method since I'm eager to understanding how js works under the hood (at least to nighing considerably to it) and feeling comfortable with it.

Note

I know there are posts here on this topic, but i think those don't meet my needs, considering those which (are very good) dig deep into it are from around 2012.

With class and extend keywords way

REFERENCE: https://www.geeksforgeeks.org/how-to-extend-an-object-in-javascript/

// Declaring class 
class Profile {

  // Constructor of profile class 
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  getName() {

    // Method to return name 
    return this.name;
  }

  getAge() {

    // Method to return age 
    return this.age;
  }

  getClass() {
    return this;
  }
}

// Class Student extends class Profile  
class Student extends Profile {

  // Each data of class Profile can be 
  // accessed from student class. 
  constructor(name, age, languages) {

    // Acquiring of attributes of parent class 
    super(name, age);
    this.lang = [...languages];
  }

  // Method to display all attributes 
  getDetails() {
    console.log("Name : " + this.name);
    console.log("Age : " + this.age);
    console.log("Languages : " + this.lang);
  }
}

// Creating object of child class with passing of values 
var student1 = new Student("Ankit Dholakia", 24,
  ['Java', 'Python', 'PHP', 'JavaScript']);
student1.getDetails();

I tried this... but I'm not comfortable!

function Person(name, age) {
  this.name = name;
  this.age = age;
}
Person.prototype.selfPresentation = function() {
  console.log("Hello, my name is " + this.name + "and I'm " + this.age + " years old.");
}

function Worker(name, age, occupation) {
  Person.call(this, name, age);
  this.occupation = occupation;
}
Worker.prototype = new Person;
Worker.prototype.selfPresentation = function() {
  // I think there undoubtedly is a best approach for this...
  this.__proto__.__proto__.selfPresentation.call(this); 
  console.log("I don't breath only, I'm a " + this.occupation);
}

let variable = new Worker("Arturo", 22, "Student");
variable.selfPresentation();

(This is a little aside my goal but..) For inheritance between objects I tried to mimic Object.create method

a = {
  field: "field",
  method: function() {
    console.log("SuperMethod");
  }
}

function inheritHimAll(object) {
  function helperFunction() {}
  helperFunction.prototype = object;
  return new helperFunction;
}

b = inheritHimAll(a);
console.log(b.__proto__)

What would be the best approach for extending objects in javascript?

  • Why would you try to mimic `Object.create` instead of just using it? Notice that is the most basic primitive in JS object inheritance. – Bergi Oct 07 '20 at 18:11
  • Define "best".. – Wiktor Zychla Oct 07 '20 at 18:11
  • 1
    Why do you say "JavaScript 2020" when you're actually asking about the *old* way of doing it? The `class` syntax is the 2020 way. – Barmar Oct 07 '20 at 18:12
  • Why would you avoid ES6 classes? They represent C-like classes which is much better than the nitty-gritty prototype nightmare that came before it... – Mr. Polywhirl Oct 07 '20 at 18:12
  • @Mr.Polywhirl He said: **I'm eager to understanding how js works under the hood** – Barmar Oct 07 '20 at 18:13
  • 3
    Using `Worker.prototype = new Person;` is [discouraged](https://stackoverflow.com/q/17392857/1048572) and using `__proto__` is outright deprecated. – Bergi Oct 07 '20 at 18:13
  • 1
    @Mr.Polywhirl No, they do *not* represent C-like classes. They do represent prototypical inheritance, just with nicer syntax. (Apart from the fact that C has no `class`es). – Bergi Oct 07 '20 at 18:14
  • Even though I know how the prototype chain works and stuff like that, I prefer to use the `class` syntax because it's much more intuitive and less error-prone. I think many other JS programmers feel that way. – D. Pardal Oct 07 '20 at 18:14
  • I guess i used wrong terminologies, what i want is to make this happen correctly without recoursing to class and extend keywords, this is more for conceptual understanding, just that. Indeed @Barmar, that's why i tried to clarify im attempting to have more culture regarding to this. – Arturo Bolívar Labaut del Río Oct 07 '20 at 18:15
  • 1
    If you want to compare two ways of doing something, it would be better if you actually implemented the same functionality in both snippets. Why is one of them `Person/Student` and the other `Perso/Worker`, and the methods are all different? – Barmar Oct 07 '20 at 18:18
  • @Mr.Polywhirl, C doesnt have classes as far as im aware, but C++ does. – Arturo Bolívar Labaut del Río Oct 07 '20 at 18:19
  • The following links might help, if you had not already seen them: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes and also https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain – BenKoshy Oct 07 '20 at 18:20
  • I said, "C-like" not "C". I know that C only has structs, but other C-like languages that follow OOP have very similar structures, but you and I digress... – Mr. Polywhirl Oct 07 '20 at 18:20
  • @Barmar, you are correct, the first example is exactly one that was mentioned in a post of GeeksForGeeks, which i didnt reference, the other one is mine, that's why there exists a difference between class names. – Arturo Bolívar Labaut del Río Oct 07 '20 at 18:22

1 Answers1

0

What would be the best approach for extending objects in javascript?

This is quite a subjective question, but I use the class syntax when I can. They are more intuitive, and require less boilerplate code.

However, I think you are more interested in knowing how to do inheritance without the class syntax. Here's what I would change from your example:

  1. Don't create a new instance of the class for prototype. The properties all live in the object, not in the prototype. Instead, use Object.create() to create a new object with the class's prototype. See this answer for more information about this.
  2. Never use __proto__. Instead, call the function from the class's prototype manually or use Object.getPrototypeOf().
function Person(name, age) {
  this.name = name;
  this.age = age;
}
Person.prototype.selfPresentation = function() {
  console.log("Hello, my name is " + this.name + "and I'm " + this.age + " years old.");
}

function Worker(name, age, occupation) {
  Person.call(this, name, age);
  this.occupation = occupation;
}
Worker.prototype = Object.create(Person.prototype);
Worker.prototype.selfPresentation = function() {
  Person.prototype.selfPresentation.call(this); 
  console.log("I don't breath only, I'm a " + this.occupation);
}

let variable = new Worker("Arturo", 22, "Student");
variable.selfPresentation();
D. Pardal
  • 6,173
  • 1
  • 17
  • 37