Why the `this` behaves different when inherit in JavaScript and Java?

84 Views Asked by At

I got doubt with the behavior that this is different in JavaScript and Java when inherit.

In java:

class Animal {
    public String name = "animal";

    void hello() {
        System.out.println("hello " + this.name);
    }
}

class Dog extends Animal {
    public String name = "dog";
}

public class Main {
    public static void main(String...args) {
        Dog dog = new Dog();
        dog.hello(); // hello animal
    }
}

The code above will output hello animal, it seems when I call the hello method in the instance of the subclass Dog, it will output the name property in parent class Animal.

but it is different in Javascript:

class Animal {
    constructor() {
        this.name = 'animal';
    }

    hello() {
        console.log('hello ' + this.name);
    }
}

class Dog extends Animal {
    constructor() {
        super();
        this.name = 'dog';
    }
}

const dog = new Dog();
dog.hello(); // hello dog

As you see, the code with the same logic output different result. In JavaScript code, the hello method output hello dog, it is the name property of subclass instance.

I also try Python and C++, the result is Python behaves like JavaScript and the C++ behaves like Java.

So does it because JavaScript and Python is dynamic language? but what is the detail about this and why they are designed as this?

and which book i should read to know about it?

thanks a lot, forgive for poor English...

2

There are 2 best solutions below

0
On

In C++ and Java, only functions can be virtual (that is, looked up dynamically). Whereas in Python and JavaScript, all properties/attributes/fields are looked up dynamically. Presumably C++ and Java didn't want the language to promise more than could be implemented with zero or low overhead. Whereas Python and JavaScript are less concerned with overhead and more concerned with making the language just do what you want.

If you wanted C++ to behave like JavaScript, then you'd have to write a virtual accessor function to access the appropriate field.

class Animal {
  string name_;

  public:
    Animal() : name_ {"animal"} {
    }

    virtual string name() const {
      return name_;
    }

    void hello() {
        cout << "hello " << name();
    }
};

class Dog : public Animal {
  string name_;

  public:
    Dog() : name_ {"dog"} {
    }

    string name() const override {
      return name_;
    }
};

int main() {
  Dog dog;
  dog.hello(); // hello dog
}
1
On

MDN is a start.

Most Javascript books aimed at programmers will cover 'this'.

There is a list of books in the Learning Javascript section. There are several free books on the web.