Доступ к полю класса в суперклассе

1

У меня есть файл со следующим кодом:

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 и всю путаницу, которую он вызывает.

Есть ли способ получить доступ к классу класса суперкласса?

  • 1
    Функции стрелок в свойствах класса могут быть не такими хорошими, как мы думаем - используйте вместо этого правильные методы!
  • 2
    За что это было?
Показать ещё 6 комментариев
Теги:
ecmascript-6
babeljs

1 ответ

3

Почему это происходит? Я предполагаю, что супер нельзя использовать для доступа к полю класса

Да. Поля класса - это свойства экземпляра, но 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)
}
  • 0
    Благодарю. Я попробовал вашу идею superDoSomething . Это немного странно, но это работает, и это лучшее, что мне удалось придумать.
  • 0
    Конечно, это странно, но это единственное, что вы можете сделать, если будете настаивать на использовании функций стрелок в качестве свойств экземпляра ...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню