Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

avoiding super ambiguity #339

Open
Bamieh opened this issue Sep 14, 2016 · 2 comments
Open

avoiding super ambiguity #339

Bamieh opened this issue Sep 14, 2016 · 2 comments

Comments

@Bamieh
Copy link

Bamieh commented Sep 14, 2016

I'm reading your book and its a great read so far! thanks.

In the classes section, talking about super you mentioned the following:

3.The only way to avoid calling super() is to return an object from the class constructor.

Can you please further elaborate why would you need to avoid using super? and what do you mean by "return an object from the class constructor."? does this object becomes the new "this"?

@nzakas
Copy link
Owner

nzakas commented Sep 14, 2016

Returning an object from a constructor:

class Foo extends Bar {
    constructor() {
        let o = new Bar();
        o.somethingCustom = true;
        return o;
    }
}

I don't know when you'd want to do such a thing, I only know that it's possible.

When you return an object from the constructor, it's the same as returning an object from a function. There is no relationship to this inside of the class methods.

@Bamieh
Copy link
Author

Bamieh commented Mar 19, 2017

@nzakas coming back to this half a year later, the object returned from the constructor is the one assigned to the constructed class's own properties.

example:

lets create a base class

class BaseClass {
   constructor() {
       this.state = "I am base.";
   }
}

normal case (calling super method):

class NormalCase extends BaseClass {
   constructor() {
      super();
   }
}
new NormalCase().state // "I am base."

Returning an object from constructor

class ReturnObject extends BaseClass {
   constructor() {
       return {}
   }
}
new ReturnObject().state // undefined
class ReturnObject2 extends BaseClass {
   constructor() {
      return {state: "I am ReturnObject2."}
   }
}
new ReturnObject2().state // "I am ReturnObject2."
class ReturnObject3 extends BaseClass {
   constructor() {
      super() //return overrides it
      return {state: "I am ReturnObject3."}
   }
}
new ReturnObject3().state // "I am ReturnObject3."

finally, it has nothing to do with super or inheritance at all.

class ReturnObjectBaseClass {
   constructor() {
       return {
          state: "I am ReturnObjectBaseClass."
       }
   }
}
new ReturnObjectBaseClass().state // "I am ReturnObjectBaseClass."

So in conclusion:

  • Any class returning an object from its constructor the returned object will be assigned to its this.
  • An extending class must return an object from its constructor to be assign to its this unless super was called, which will return the extended classes own properties implicitly at the end of the constructor call.

possible use case:
You need to extend a class just for its providing methods, not to add the extended class own properties to the new class.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants