Быстро Найти Источник Нежелательных Мутаций В Свойстве Объекта.

Привет! Сегодня я расскажу вам, как можно использовать отладчик для решения, на мой взгляд, нетривиальной проблемы JavaScript. В JavaScript объекты представляют собой составной тип данных; их значение передается по ссылке.

Другими словами, когда мы передаем объект функции в качестве параметра или где угодно, мы можем изменить его свойства.

Использование инструкции, состоящей из выражения для переменной, хранящей ссылку, а также операторов точки и присваивания.

После этого другие инструкции, которые работают или будут работать с этой переменной/параметром, получат изменение свойства по ссылке.

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

Поиск источника таких нежелательных изменений свойств может занять много времени: программа уже может быть большой и состоять из сотен тысяч инструкций.

Давайте посмотрим на простой пример.

  
  
  
  
  
  
   

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Debug property mutation example</title> <script> const user = { firstName: 'Vasilij', middleName: 'Alibabaevich', lastName: 'Radner', aka: 'Alibaba', getFullName() { return `${this.lastName} ${this.firstName.slice(0, 1)}.

${this.middleName.slice(0, 1)}.

` } }; </script> <script src="object-property-mutation.js" type="application/javascript"></script> </head> </head> <body> <script> Promise.resolve(user).

then(user.getFullName.bind(user)).

then(console.log); </script> </body> </html>

Сейчас веб-программа не работает, так как в консоли ошибка и не выводится полное имя.



Быстро найти источник нежелательных мутаций в свойстве объекта.
</p><p>

Читаем верхнее сообщение в консоли:

Uncaught (in promise) TypeError: Cannot read property 'slice' of undefined

Ошибка типа не обработана (в обещании): невозможно прочитать фрагмент свойства из неопределенного.

Нажмите на ссылку и перейдите к месту ошибки.



getFullName() { return `${this.lastName} ${this.firstName.slice(0, 1)}.

${this.middleName.slice(0, 1)}.

` }

Мы видим, что выражение ошибочно

this.firstName.slice(0, 1)

состоит из четырех операторов:
два точечных оператора один оператор-разделитель-запятая один оператор группировки — пара круглых скобок Давайте прочитаем инструкцию.

Левое выражение вычисляется первым

this.firstName

Он состоит из оператора точки, основного выражения this слева и идентификатора firstName справа.

Результат этого выражения будет неопределенным.

Выполнение следующего оператора точки вызывает ошибку.

Поскольку оператор точки работает только с типами объектов, его выполнение из неопределенных результатов приводит к ошибке — я не могу получить свойство среза из неопределенных.

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

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

Двигаясь вниз по стеку вызовов от места ошибки, попробуем перейти к инструкции, которая изменила свойство.



Выбор инструмента остановки при исключении



Быстро найти источник нежелательных мутаций в свойстве объекта.
</p><p>

Мы видим, что в стеке всего два вызова.

Перейдем к предыдущему звонку.



Быстро найти источник нежелательных мутаций в свойстве объекта.
</p><p>

Мы видим, что нет явной инструкции, изменяющей свойство firstName.

Быстро найти источник нежелательных мутаций в свойстве объекта.
</p><p>

Делаем вывод, что в этом стеке вызовов изменений не происходит.


Как вам это нравится?

И как найти злодея, который изменил свойство моего объекта? Напишите, пожалуйста, в комментариях, как бы вы его нашли? Ребята, кто со мной работает и кому я это рассказал, напишите, пожалуйста, звездочку в комментарии.

Мне очень интересно услышать, как другие специалисты по JavaScript решают подобные проблемы.

Знаете, когда я впервые столкнулся с таким поведением JavaScript, я потратил пару часов на изучение и вырвал клок волос из своей челки.

Отключите инструмент «Пауза при исключении».

Итак, вот наш новый план: мы определим свойство firstName в объекте пользователя, используя методы получения и установки.

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



const user = { _firstName: 'Vasilij', set firstName(value) { debugger; this._firstName = value; }, get firstName() {return this._firstName}, middleName: 'Alibabaevich', lastName: 'Radner', aka: 'Alibaba', getFullName() { return `${this.lastName} ${this.firstName.slice(0, 1)}.

${this.middleName.slice(0, 1)}.

`; } };

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

Быстро найти источник нежелательных мутаций в свойстве объекта.
</p><p>

Мы видим, что значение параметра value не определено.

Теперь, используя стек вызовов, мы можем легко перейти к предыдущему вызову.



Быстро найти источник нежелательных мутаций в свойстве объекта.
</p><p>

иаааа победа, ура.

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

остановиться на исключении .

Вот наш новый план: сделать объект пользователя не объектом и с помощью инструмента остановка исключения , мы легко получим ошибочные инструкции.

Так как мы знаем, что при попытке получить свойство из undef возникает ошибка.

Мы включаем инструмент остановки при исключении и присваиваем значение undef пользовательской переменной.



const user = undefined;

Мы снова остановились на точке повреждения свойства firstName.

Быстро найти источник нежелательных мутаций в свойстве объекта.
</p><p>

Это все, что я хотел вам сегодня рассказать об отладке нежелательных изменений объектов.

Спасибо за прочтение статьи.

Ставьте лайк, подписывайтесь на канал, делитесь этим видео и статьей с друзьями, всего доброго.

github.com/NVBespalov/js-lessons/tree/error/property-mutation Теги: #JavaScript #отладка #отладка #инструменты отладки

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.