Проксирование объекта window для обнаружения изменений

#javascript #ecmascript-6 #proxy #window

#javascript #ecmascript-6 #прокси #окно

Вопрос:

Могу ли я проксировать window объект для обнаружения изменений? Я попробовал следующее, но безуспешно:

 var handler = {
  get: function(target, property) {
    console.log("getting "   property   " for "   target);
    return target[property];
  },
  set: function(target, property, value, receiver) {
    console.log("setting "   property   " for "   target   " with value "   value);
    target[property] = value;
    return true;
  },
};
var p = new Proxy(window, handler);
setTimeout(() => {
  window.a = 10; // expecting a log, but nothing...
}, 3000);
setTimeout(() => {
  window.c = 20; // expecting a log, but nothing...
}, 4000);  

Ответ №1:

Вы должны ссылаться на экземпляр прокси-сервера в вашем нижнем коде, а не на window :

 var handler = {
  get: function(target, property) {
    console.log("getting "   property   " for "   target);
    return target[property];
  },
  set: function(target, property, value, receiver) {
    console.log("setting "   property   " for "   target   " with value "   value);
    target[property] = value;
    return true;
  },
};
var p = new Proxy(window, handler);

setTimeout(() => {
  p.a = 10;    // <------------
}, 300);
setTimeout(() => {
  p.c = 20;    // <------------
}, 400);  

Если вы не можете изменить код, который ссылается на window , вы могли бы также присвоить имя прокси window (и сохранить ссылку на истинное окно в другой переменной), но код для этого выглядел бы запутанным.

Если он находится в отдельном файле сценария, описанный выше трюк не сработает, и вы не сможете использовать Proxy — в конце концов, вы не можете переопределить объект window. Если вы ищете изменение для определенного свойства на window , вы могли бы использовать defineProperty и заставить установщик перезаписать дескриптор свойства новым значением, когда оно будет присвоено:

 Object.defineProperty(window, 'a', {
  configurable: true,
  set(value) {
    console.log("setting with value "   value);
    Object.defineProperty(window, 'a', { value });
  }
});

setTimeout(() => {
  window.a = 10;
  console.log(window.a);
}, 300);  

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

1. Но мне нужно только обнаружить изменения на window . Вариант использования — проверить, window.pluginX затем инициализировать плагин. Потому что плагин при загрузке добавляет prop pluginX в window , поэтому мне просто нужно проверить это и сделать свое дело.

2. @eozzy вы смогли это решить? Я также хочу прослушать изменения в свойстве window и на основе этого внести изменения в глобальную переменную, которая указывает на это свойство window.

3. @ZameerHaque Преобразуйте свойство window, которое вы хотите прослушать, в средство получения / установки.

4. Да, в итоге я это сделал. Проксирование было бы замечательно, поскольку совместно используемому модулю, который обращается к свойству window, не нужно было бы изменять подпись для вызова свойства.