3

I'm familiar with prototypes quite well and now I try to understand how classes work by testing how they look like under the hood when compiled and compare it with 'prototypal' approach.

When I use prototypes, I can "extend" one object to another with Object.setPrototypeOf method. I pass as the second argument anything that is of [Object] type and it works, but when I use extends keyword with class, it expects only another [class] type object.

This is the working prototype-like approach:

function Citizen(country){
  this.country = country;
}

function Student(subject){
  this.subject = subject;
}


Object.setPrototypeOf(Student.prototype,new Citizen('Poland'));

var student = new Student('IT');
console.log(student.subject); //IT
console.log(student.country); //Poland

So, I "extends" the Student onto Citizen instance rather than Citizen itself (constructor). And it works just fine. I have the access to the properties of Citizen instance (student.contry).

How can I get the same result with the class and extends? I want to achieve something like in the code below, but it throws error: Class extends value #<Citizen> is not a constructor or null, what seems to be not as flexible as the use of pure prototypes.

class Citizen {
  constructor(subject){
    this.subject = subject;
  }
}

class Student extends new Citizen('USA') { 
  //this expects CLASS rather than instance of the class
  //Error: Class extends value #<Citizen> is not a constructor or null
  constructor(subject){
    this.subject = subject;
  }
}

var student = new Student('law');

console.log(student.subject); //law
10
  • "And it works just fine." - No, it doesn't Commented Nov 8, 2017 at 18:48
  • Do not use Object.setPrototypeOf for this. Not sure where you got that from. Commented Nov 8, 2017 at 18:48
  • 2
    "class seems to be not as flexible as the use of pure prototypes." - it never was meant to. Classes provide a relatively rigid framework that is hard to mess up. Commented Nov 8, 2017 at 18:50
  • @Bergi from mdn. and why? Commented Nov 8, 2017 at 19:33
  • 1
    @Paweł No, extends is fine - it's more akin to Object.create than to setPrototypeOf. Commented Nov 8, 2017 at 20:02

1 Answer 1

1

How can I get the same result with the class and extends?

You can't (-ish). But more importantly, you shouldn't. Even with the prototype approach, you still shouldn't. Your prototype approach should look like this:

Object.setPrototypeOf(Student.prototype, Citizen.prototype);

And likewise, your class approach should look like this:

class Student extends Citizen

And if for some reason you want your Student to have a hardcoded country, then you'd do that like this:

class Student extends Citizen {
    constructor(subject) {
        super("USA");
        this.subject = subject;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.