У меня есть файл со следующим кодом:
class Animal {
doSomething = () => {
return 'Hi.';
};
}
class Dog extends Animal {
doSomething = () => {
return super.doSomething() + ' Woof!';
};
}
console.log(new Dog().doSomething());
Примечание: попытка выполнить фрагмент выше, вероятно, не будет работать, потому что я не могу понять, как заставить его использовать настройки моего Babal.
Во всяком случае, когда я скомпилирую его с помощью Babel и запускаю его в узле, я получаю следующую ошибку:
/Users/elias/src/classFieldTest/build/classFieldTest.js:15
return super.doSomething() + ' Woof!';
^
TypeError: (intermediate value).doSomething is not a function
at Dog.doSomething (/Users/elias/src/classFieldTest/build/classFieldTest.js:15:26)
at Object.<anonymous> (/Users/elias/src/classFieldTest/build/classFieldTest.js:21:23)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Function.Module.runMain (module.js:693:10)
at startup (bootstrap_node.js:188:16)
at bootstrap_node.js:609:3
Я использую Babel 6.26.0 с предустановкой stage-2
и Node 8.11.1. Я могу показать команды, которые я использую, если кто-то заботится.
Почему это происходит? Я предполагаю, что super
нельзя использовать для доступа к классу, но что я должен делать? Если я изменил метод doSomething
Animal
на традиционный метод (doSomething() { return 'Hi.'; }
), Он работает, но я предпочел бы избегать традиционных методов, так как они переопределяют this
и всю путаницу, которую он вызывает.
Есть ли способ получить доступ к классу класса суперкласса?
Почему это происходит? Я предполагаю, что супер нельзя использовать для доступа к полю класса
Да. Поля класса - это свойства экземпляра, но super
пытается получить доступ к свойствам объекта прототипа суперкласса. У вашего класса Animal
просто нет метода doSomething
- вместо этого каждый объект Animal
имеет свойство, которое содержит связанную функцию.
но что я должен делать? Если я изменю его на традиционный метод, он будет работать
Да, вы должны делать именно это. Вот как работают методы и super
.
Избегайте стрелок, когда они вам не нужны, и особенно когда они не работают. Также взгляните на функции стрелок в свойствах класса, возможно, не так велики, как мы думаем.
Есть ли способ получить доступ к классу класса суперкласса?
Да - это свойство экземпляра, и вы можете получить к нему доступ в своем конструкторе, прежде чем перезаписать его:
class Animal {
constructor() {
this.doSomething = () => {
return 'Hi.';
};
}
}
class Dog extends Animal {
constructor() {
super();
const superDoSomething = this.doSomething;
this.doSomething = () => {
return superDoSomething() + ' Woof!';
};
}
}
В качестве альтернативы, с предложением полей классов и без явного конструктора:
class Animal {
doSomething = () => {
return 'Hi.';
}
}
class Dog extends Animal {
doSomething = (superDoSomething => () => {
return superDoSomething() + ' Woof!';
})(this.doSomething)
}
superDoSomething
. Это немного странно, но это работает, и это лучшее, что мне удалось придумать.