Почему нет доступа к переменной

Почему нет доступа к переменной в классе?

class Block {

    private value: string;
    private options: IBlockOptions;

    constructors = {
        ImageBlock: ImageBlock
    }

    static factory(Type: string) {
        if(constructors // не удается найти, так же и с Block.constructors) {

        }
    }

    constructor(value: string, options: IBlockOptions) {
        this.value = value;
        this.options = options;
    }

}

Почему так происходит? и как я могу добиться доступа к переменной класса(функции?)


Ответы (1 шт):

Автор решения: Арман

Ответ

Static поля и функции не видят нестатичных членов класса.

Почему?

Надо понять - кто такие статичные члены класса? Перепишем класс вот так:

class Block {
    //#region Static
    static factory(Type: string) {
        // Какой-то код
    }
    //#endregion
    //#region Non-Static
    constructor(value: string, options: IBlockOptions) {
        this.value = value;
        this.options = options;
    }
    private value: string;
    private options: IBlockOptions;
    constructors = { ImageBlock: ImageBlock }
    //#endregion
}

То что внутри региона Static общий для всех эксемпляров класса. То есть:

class Block
    static data = 5;
}
console.log(Block.data) // 5
const block1 = new Block();
console.log(block1.data) // 5
Block.data = 4;
console.log(Block.data) // 4
console.log(block1.data) // 4
block1.data = 3;
console.log(Block.data) // 3
console.log(block1.data) // 3
const block2 = new Block();
console.log(block2.data) // 3

И поскольку статические переменные общие, они "не видят" не общих членов класса. Для них они просто не существуюит.

class Block
    data = 5;
    static getData() {
        return Block.data // Ошибка: Block.data не существует
    }
}

Начало существования не статичных переменных это вызов конструктора. То есть они создаются во время вызова конструктора. Поэтому их лучше писать ниже статичных переменных и конструктора (это не правило, так просто понятнее будет). А вот во время их создания статичные члены уже существуют и не статичные члены могут к ним обратится.

class Block {
    static data = 5;
    constructor () {} // Конструктор пишу для наглядности
    getData() {
        return Block.data
    }
}
const block1 = new Block(); // Конструктор вызван, не статичные поля созданы
block1.getData() // 5

Решение

Один из решений выглядит так:

class Block {
    static factory(instance: Block, Type: string) {
        if (instance.constructors) {
            // Какой-то код
        }
    }
    constructor(value: string, options: IBlockOptions) {
        this.value = value;
        this.options = options;
    }
    private value: string;
    private options: IBlockOptions;
    constructors = { ImageBlock: ImageBlock }
}
const block1 = new Block(/* аргументы */);
Block.factory(block1, ``);
→ Ссылка