Рубрики
Без рубрики

Объект, который плохо себя ведет – окно.Подверга.

Как я устраняю проблемы, которые не имеют смысла сегодня, мы хотели начать отслеживать … Теги с JavaScript, исследованиями, устранением неполадок, производительностью.

Сегодня мы хотели начать отслеживать некоторые новые показатели производительности на наших посадочных страницах, а более конкретно, использование памяти. Как обычно, мы получили данные из нашего доверия Window.Performance Объект (отныне будет называться «врагом» ), затронул его перед отправкой и …

Удивительно, что все, что мы получили, было "{}" Действительно

Как это может быть? У нас есть объект, с свойствами, которые мы можем получить доступ, но строгая его возвращает пустой объект!

Вниз в кроличью нору я пошел

Я начал копать глубже в нее, с целью поворота враг в строку без жесткого кодирования имен свойств.

Я пытался распространять его
  const result = { ...window.performance.memory };
  console.log(result); // {}
Я пытался получить свои компоненты
  const keys = Object.keys(window.performance.memory);
  const values = Object.values(window.performance.memory);
  console.log(keys); // []
  console.log(values); // []
Я пытался разрушить его
  const { jsHeapSizeLimit } = window.performance.memory;
  console.log(jsHeapSizeLimit); // 2330000000

И удивительно – это сработало!

С большой уверенностью, что я собираюсь взломать это, я попробовал «отдых» разрушительствовать:

  const { ...rest } = window.performance.memory;
  console.log(rest); // {}

Что здесь происходит? Почему этот конкретный объект отказывается играть в приятно?

Свет в конце туннеля (который оказывается поездом)

После того, как еще немного звонил, я нашел еще одну вещь, которая не имеет смысла.

  for (const prop in window.performance.memory)
    console.log(`${prop}: ${window.performance.memory[prop]}`)
  // totalJSHeapSize: 13400000
  // usedJSHeapSize: 12700000
  // jsHeapSizeLimit: 2330000000

Итализация по свойствам противника работает, но не получает его имена свойств? Даже объект.GETOWNPROPERTYNAMES не удалось!

Хотя это решение может работать для меня (помните, что моя оригинальная цель была «поворота враг в строку без жесткого кодирования имен недвижимости») Я хотел найти более элегантное решение, и хотел добраться до дна этого.

Первое решение, ака “не достаточно хорош”

Следующая часть моей поездки была, когда я начал играть с прототипом враг называется Memoryinfo Отказ Я пытался изменить прототип, присвоение враг Для нового объекта с другим прототипом, создавая массив от врага и в конечном итоге играя в сочетание всех методов, упомянутых выше.

  Object.getOwnPropertyNames(window.performance.memory); // []
  Object.getOwnPropertyNames(window.performance.memory.__proto__) // 
  ["totalJSHeapSize", "usedJSHeapSize", "jsHeapSizeLimit", "constructor"]

Успех! Ну … вроде. Я получил имена свойств прототипа, и я мог бы использовать этот массив, чтобы получить то, что я хочу использовать следующий фрагмент

  const success = JSON.stringify(Object.getOwnPropertyNames(window.performance.memory.__proto__).reduce((acc,key) => {
       if (key !== 'constructor')
         acc[key] = window.performance.memory[key];
       return acc;
    }, {})
  );

  console.log(success) // " {"totalJSHeapSize":20500000,"usedJSHeapSize":18200000,"jsHeapSizeLimit":2330000000}"
Не отлично, не ужасно.

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

Я один с кодом

Быстро вперед 1 час И я обнаружил, что объекты имеют свойства, и эти свойства имеют метаданные (называемые дескриптором), и эти метаданные определяют, сможем ли мы перечислять его на свойство, изменить его, и как мы получаем его от объекта.

Таким образом, должно быть, что свойства имеют какой-то тег метаданных, который предотвращает их получать их обычными способами. От MDN я подумал, что перечислимый Это имущество, которое интересует меня:

правда Если и только если это свойство появляется во время перечисления свойств на соответствующем объекте.

  Object.getOwnPropertyDescriptors(window.performance.memory.__proto__);
// {..., jsHeapSizeLimit: {get: ƒ, set: undefined, enumerable: true, configurable: true}, ...}

Но свойства имеют перечислимый Свойство метаданных включено, почему они не отображаются при использовании Объект. Keys или Object.values ?

Неапо-Гранд Финал

Наконец, мне удалось «включить» перечислимые флаги на враг и мои данные строгали красивые

  const finale = JSON.stringify(Object.defineProperties(window.performance.memory, Object.getOwnPropertyDescriptors(window.performance.memory.__proto__)));
  console.log(finale); // "{"totalJSHeapSize":29400000,"usedJSHeapSize":23100000,"jsHeapSizeLimit":2330000000}"
Сладкий, сладкий одноклассник

Так что тут происходит?

Мы уже видели, что дескрипторы Memoryinfo прототип должен быть в порядке, поэтому единственное объяснение так, что как-то они не установлены (или переопределены) на враг сам.

Использование Объект.defineproperties Я могу получить копию враг , но с правильными дескрипторами (которые мы можем просто получить от прототипа, используя object.getownpropertydescriptors )

Тогда просто строгла и отправляйтесь!

Оригинал: “https://dev.to/oryanmoshe/the-object-that-misbehaved-window-performance-memory-5hag”