Почему `this` ведет себя по-разному, когда наследуется в JavaScript и Java?

У меня есть сомнения с поведением, что this отличается в JavaScript и 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
    }
}

Код выше выведет hello animalКажется, когда я вызываю метод hello в экземпляре подкласса Dog, он выводит свойство name в родительском классе Animal.

но это отличается в 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

Как видите, код с одинаковой логикой выводит другой результат. В коде JavaScript вывод метода hello hello dog, это свойство name экземпляра подкласса.

Я также пробую Python и C++, в результате Python ведет себя как JavaScript, а C++ ведет себя как Java.

Так ли это, потому что JavaScript и Python - это динамический язык? но что в этом подробного и почему они разработаны так?

и какую книгу я должен прочитать, чтобы узнать об этом?

спасибо, простите за плохой английский...

2 ответа

В C++ и Java только функции могут быть виртуальными (то есть, динамически проверяться). В то время как в Python и JavaScript все свойства / атрибуты / поля ищутся динамически. Предположительно C++ и Java не хотели, чтобы язык обещал больше, чем можно было бы реализовать с нулевыми или низкими издержками. В то время как Python и JavaScript меньше заботятся о накладных расходах и больше заботятся о том, чтобы заставить язык делать то, что вы хотите.

Если вы хотите, чтобы C++ вел себя как JavaScript, вам нужно было бы написать функцию виртуального доступа, чтобы получить доступ к соответствующему полю.

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
}

MDN это начало.

Большинство книг Javascript, предназначенных для программистов, будут охватывать "это".

В разделе Learning Javascript есть список книг. В Интернете есть несколько бесплатных книг.

Другие вопросы по тегам