Инициализация поля в подклассе происходит после завершения конструктора в родительском классе в javascript.Это по замыслу? - PullRequest
0 голосов
/ 28 сентября 2019

Это проще показать, чем описать.Вот код

let ns = {};

ns.A = class {
    constructor() { 
        this.Virtual();
    }   

    Virtual() {
    }
};

ns.B = class extends ns.A {
    constructor() {
        super();
        alert(this.Field);
    }

    Field = 0;  

    Virtual() {
        this.Field = 123;
    }
}

alert() говорит, что this.Field равно 0. То есть инициализация поля в классе B выполняется после завершения конструктора A.Это «по замыслу» в Javascript?

Если я добавлю Field в прототип класса B, то все будет хорошо, как и на любом другом языке.Например,

let ns = {};

ns.A = class {
    constructor() { 
        this.Virtual();
    }   

    Virtual() {
    }
};

ns.B = class extends ns.A {
    constructor() {
        super();
        alert(this.Field);
    }

    //Field = 0;    

    Virtual() {
        this.Field = 123;
    }
}

ns.B.prototype.Field;

Извините, что беспокою вас здесь, но я не знаю, где находится правильное место, чтобы сообщить об этой проблеме.

1 Ответ

1 голос
/ 28 сентября 2019

С https://github.com/tc39/proposal-class-fields#execution-of-initializer-expressions:

Когда вычисляются инициализаторы поля ...

Базовый класс: в начале выполнения конструктора ...

Полученокласс: сразу после супер () возвращает ...

Иллюстрация:

class A {
    constructor() {
        console.log('A constructor start');
        this.Virtual();
        console.log('A constructor end');
    }

    Field = (() => { console.log('A field init'); return 1})()

    Virtual() {
    }
};

class B extends A {
    constructor() {
        console.log('B constructor start')
        super();
        console.log('B constructor end')
    }

    Field = (() => { console.log('B field init'); return 2})()

    Virtual() {
        console.log('B virtual')
        this.Field = 123;
    }
};

console.log(new B())

То есть в вашем коде Field = 0 происходит после this.Field = 123, перезаписывая его.Порядок объявлений не имеет значения.

Если у вас есть проблемы с этим поведением и вы хотите его обсудить, https://github.com/tc39/proposal-class-fields/issues будет правильным местом.

...