Electron.js повторная привязка к global — bind(), call() работает не так, как предполагалось

#javascript #node.js #electron

#javascript #node.js #electron

Вопрос:

Итак, я переношу свою кодовую базу в электронную оболочку и устраняю проблемы.

Одним из которых является то, что я разработал фабрику, которая создает «Плагины», я загружаю в нее функции, данные и другие вещи (например, смонтированные функции и т.д.). Аналогично тому, как Vue создает свои компоненты.

videobridgeTransmitter.js :

 const videoBridgeTransmitter = {
    id: 'videobridge',
    data: {
        availableSources : [], //available Sources that can be streamed
        selectedSources: [], //selected sources by the user
        shared: {
            activeClients: []
        }
    },
    mounted: function(){
        console.log(this.client) //prints global

        this.client.setPluginData('videobridge', {
            streams : [],
            addStream(stream, alias, deviceID){
              this.streams.push({
                  alias: alias,
                  deviceID : deviceID,
                  dataStream : stream
              })
            }, ...
  

В классе factory я повторно привязываю все методы к новому экземпляру:

 //rebind "this" to the plugin object, so that we can access the plugin from the methods
    const methodKeys = Object.keys(methods);
    for (let i=0;i < methodKeys.length;i  ){
      methods[methodKeys[i]] = methods[methodKeys[i]].bind(this);
    }
  

Методы позже вызываются через plugin.methods.xyz (аргументы);

При первом запуске экземпляра я вызываю его смонтированную функцию:

   if (typeof plugin.mounted === 'function'){
    plugin.mounted.call(this);
  }
  

Все это работало нормально. Однако в electron я сталкиваюсь с проблемой, что он сообщает мне, что «это» теперь «глобальное». Я проверил в отладчике, когда он привязывает это, он привязывает правильную область.

Однако каким-то образом, когда он затем выполняется, это возврат к «глобальному»

Комментарии:

1. Вы уже привязываетесь this к plugin.mounted , поэтому в этом нет необходимости plugin.mounted.call(this) . Весь подход здесь выглядит подверженным ошибкам. Если вы пишете систему плагинов, будут ли авторы плагинов знать о тонкостях вашего восстановления this ? По моему опыту, this это токсично и приводит к множеству ошибок, когда вы используете его таким образом. Передайте материал явно. Не привязывайте работу ваших функций к какому-либо неявному скрытому состоянию.

2. т. Е. Почему бы не изменить сигнатуру функции на function mounted(client){} и не передать ваш «runner» клиенту?

3. методы и mounted — это два разных объекта. Методы вызываются из интерфейса. Я согласен, что передача более подробная, но это казалось излишним.