Давайте разберем ваши вопросы по порядку, основываясь на типичных сценариях использования JavaScript, особенно в контексте классов и промисов.
### 1) Почему значение `this` становится `undefined`?
В JavaScript значение `this` зависит от способа вызова функции. Если функция, которую вы вызываете, не привязана к объекту (например, из-за того, что она вызвана как метод экземпляра класса), то значение `this` будет равно `undefined` или `window` в строгом режиме и нестрогом режиме соответственно.
Когда вы вызываете метод `init`, в котором используется конструкция `this.config.dbname`, `this` должен указывать на экземпляр класса. Но при использовании обычных функций (например, в обработчиках событий), `this` может ссылаться на объект, который инициировал событие, и, если этот объект не является экземпляром класса, то у вас может быть `undefined`.
Если используете стрелочные функции, они захватывают значение `this` из области, в которой были объявлены. Поэтому, если в этой области `this` все еще равно экземпляру класса, то внутри стрелочной функции `this` будет по-прежнему ссылаться на экземпляр.
### 2) Почему переменные заполняются корректно?
Возможно, что вы находитесь в контексте, где `this` всё-таки указывает на экземпляр класса, либо вы используете стрелочную функцию в каком-то месте вашего кода, где это значение сохраняется. Также может быть, что переменные инициализируются до того, как происходит потеря контекста `this`, или результат обращения к `this` в этом месте кода имеет значение, отличающееся от `undefined`.
### 3) Почему `this` соответствует `IDBOpenDBRequest`?
При использовании конструктора `IDBOpenDBRequest` и его событий, таких как `onupgradeneeded`, `this` ссылается на объект, для которого это событие произошло, то есть на сам объект `IDBOpenDBRequest`. Это является стандартным поведением JavaScript.
Если вы используете стрелочную функцию в качестве обработчика, то `this` в ней будет ссылаться на внешнюю область видимости, где эта функция была объявлена, а не на `IDBOpenDBRequest`. Однако, если вы используете обычную функциональную запись (а не стрелочную), то `this` будет ссылаться на `IDBOpenDBRequest`.
### 4) Как может вызываться метод `createStorages()`, если `this` указывает на `IDBOpenDBRequest`?
Если вы вызываете метод, как `this.createStorages()`, внутри стрелочной функции, то они могут сработать, если значение `this` во внешнем контексте действительно ссылается на экземпляр класса, а не на `IDBOpenDBRequest`. Это ещё раз подчеркивает, насколько важно понимать отличие обычных и стрелочных функций в JavaScript.
В кодах, где вы используете обработчики событий и создаёте новые функции, важно быть внимательным к тому, какое значение `this` принимает согласно месту, где вызов происходит.
### Заключение
Непреднамеренные изменения контекста `this`, возникшие из-за меток, функций, обработчиков событий и использования стрелочных функций, являются распространенной проблемой в JavaScript. Я рекомендую использовать метод `.bind(this)` для явного связывания `this` к экземпляру класса, или же основываться на стрелочных функциях там, где они того требуют.