JavaScript расширяет класс при использовании WeakMap для приватных переменных - PullRequest
2 голосов
/ 19 мая 2019

Я написал несколько классов, которые имеют частные переменные, используя WeakMap(). Я сделал это, поместив WeakMap вверху файла класса.

light.js

let privateVars = new WeakMap();

class Light {
  constructor(state, brightness) {
    let info = {"state": state, "brightness": brightness, "createdAt": Date.now()};
    // Save info into privateVars
    privateVars.set(this, info);
  }

  switch() {
    let info = privateVars.get(this);
    info.state = !info.state;
    privateVars.set(this, info);
  }
}

Это работало нормально, я смог добавить несколько методов получения и установки, которые имели проверку и проверку типов.

Теперь я хочу расширить этот класс на другой класс, но у меня возникают проблемы с разделением информации о частных свойствах между файлами дочернего и родительского классов.

flashingLight.js

let privateVars = new WeakMap();
let flashing;

import Light from './light.js';

class FlashingLight extends Light {

  constructor(state=false, brightness=100, flashMode=true) {
    super(state, brightness);
    let info = {"state": state, "brightness": brightness, flashMode: flashMode, "createdAt": Date.now()};
    privateVars.set(this, info);
    if(flashMode===true) {
      this.startFlashing();
    }
  }

  startFlashing() {
    flashing = setInterval(this.lightSwitch,5000);
  }

}

Когда this.lightSwitch вызывается из функции setInterval внутри startFlashing, он не может получить доступ к состоянию объекта.

Uncaught TypeError: Cannot read property 'state' of undefined
    at lightSwitch 

Это потому, что эти функции распределены по двум файлам? Есть ли что-нибудь подобное, чтобы я мог использовать как приватные переменные, так и расширения классов?

1 Ответ

2 голосов
/ 19 мая 2019

Одной из ваших проблем является использование setInterval , когда вы передаете функцию. Когда эта функция вызывается, this не то, что вы ожидали. Вы можете использовать bind , чтобы заставить его быть тем, что вы хотите, например setInterval(this.lightSwitch.bind(this),5000)

...