skip to Main Content
class Parent{
    method(){
        console.log("Parent");
    }
}
class Child extends Parent{
    method(){
        console.log("Parent");
    }
}
var child = new Child();
console.log(child.method);

console return method in child class which is a expected behaviour.

class Parent{
    method = "sss"
}
class Child extends Parent{
    method(){
        console.log("Child")
    }
}
var child = new Child();
console.log(child.method)

why does the console return method variable – "sss" in Parent class ?

2

Answers


  1. From MDN

    Public instance fields are added to the instance either at construction time in the base class (before the constructor body runs), or just after super() returns in a subclass.

    i.e. it masks the method because it is assigned around the time the constructor runs.

    child.method is a property (with a value that is a string) on the object itself. This masks the method on the prototype which is a function.


    The code below demonstrates.

    You can see that in example a (your code) the string value for method is a property of child itself, but you can dig through the prototype chain to get the function value from the class.

    In example b (with the public instance field removed), the method exists and can be called, but isn’t on the child itself (because its an instance of the class so it can search the prototype chain automatically because it isn’t masked).

    const a = () => {
      class Parent {
        method = "sss"
      }
      class Child extends Parent {
        method() {
          console.log("Child")
        }
      }
      var child = new Child();
      console.log("a: " + child.hasOwnProperty('method'));
      Object.getPrototypeOf(child).method();
    };
    
    a();
    
    const b = () => {
      class Parent {}
      class Child extends Parent {
        method() {
          console.log("Child")
        }
      }
      var child = new Child();
      console.log("b: " + child.hasOwnProperty('method'));
      child.method();
    };
    
    b();
    Login or Signup to reply.
  2. class Parent {
        method = "sss";
    }
    

    Is essentially a shortcut for:

    class Parent {
        constructor() {
            this.method = "sss";
        }
    }
    

    Meaning that there are some important differences with:

    class Parent {
        method() {
            console.log("Parent");
        }
    }
    
    1. In the method = "sss" variant, method will be set as an own property of the created instance (new Child()).

      child.hasOwnProperty("method") //=> true
      

      Whereas defining a normal method method() { console.log("Parent") } will not be set as an own property of the instance. Instead it is set on the prototype chain.

      Parent.prototype.hasOwnProperty("method") //=> true
      
    2. The constructor code only runs whenever you initialize an instance. Meaning that this.method = "sss" will always run after you’ve defined the Parent and Child classes (whenever you create the instance with new).

    class Parent {
        prop = "parent value";
        // aka
        // constructor() {
        //   this.prop = "parent value";
        // }
        method() {
            console.log("Parent");
        }
    }
    
    class Child extends Parent {
        prop() {
          return "child Value";
        }
        method() {
            console.log("Child");
        }
    }
    
    const child = new Child();
    
    const log = (jsString) => console.log(jsString, '//=>', eval(jsString));
    log(`child.hasOwnProperty("prop")`);
    log(`child.hasOwnProperty("method")`);
    log(`Parent.prototype.hasOwnProperty("prop")`);
    log(`Parent.prototype.hasOwnProperty("method")`);

    The final Child instance structure looks like this:

    new Child()
    // returns
    Child{ // Child instance depicted using object notation
      prop: "parent value", // set by the Parent constructor
    
      __proto__: { // Child.prototype
        prop() { return "child Value" },
        method() { console.log("Child") },
    
        __proto__: { // Parent.prototype
          method() { console.log("Parent") },
        }
      }
    }
    

    For more detailed info I suggest reading through the MDN Public class fields page.

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