Почему `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 есть список книг. В Интернете есть несколько бесплатных книг.