Приватное поле в watch и точке останова Chrome DevTools
Как добавить приватное поле класса (#region) в watch expressions и условие точки останова Chrome DevTools. Решение SyntaxError и <not available> в версиях 111+. Workaround для старых версий и Babel.
Как добавить приватное поле класса (в частности, публичное свойство приватного поля экземпляра класса) в выражение наблюдения (watch) и условие точки останова в Chrome DevTools? Автодополнение предлагает приватное свойство, но при использовании отображается <not available>, а в условии breakpoint возникает ошибка SyntaxError: Private field ‘#region’ must be declared in an enclosing class.
В Chrome DevTools версии 111 и новее приватное поле класса вроде #region добавляется в watch expressions и условие точки останова напрямую — просто введите myInstance.#region или this.#region === 'value'. Автодополнение сработает, значение отобразится без <not available>, а SyntaxError “Private field ‘#region’ must be declared in an enclosing class” исчезнет. В старых версиях ставьте точку останова внутри публичного метода класса и оценивайте this.#region в локальном scope — это обходной путь для chrome devtools до обновления.
Содержание
- Что такое приватные поля класса в JavaScript и chrome devtools
- Проблемы с точкой останова и приватное поле:
и SyntaxError - Точка останова с условием для приватных полей в chrome devtools 111+
- Workaround для старых версий chrome devtools: доступ внутри scope класса
- Проблемы с babel и private field в chrome devtools
- Лучшие практики отладки: watch expressions и chrome devtools console
- Источники
- Заключение
Что такое приватные поля класса в JavaScript и chrome devtools
Приватные поля класса в JavaScript — это фича ES2022, которая позволяет скрывать свойства от внешнего доступа с помощью префикса #. Представьте: у вас есть класс с публичным геттером, который возвращает приватное поле #region, а снаружи его не достать напрямую. Звучит идеально для инкапсуляции, правда? Но вот беда — в chrome devtools это иногда превращается в головную боль.
Chrome DevTools, основной инструмент для отладки JS, эволюционировал. До версии 111 приватные поля #privateField были недоступны вне контекста класса: автодополнение в консоли предлагало их, но при оценке — <not available>. А если пытаться в условии точки останова? SyntaxError на лицо: “Private field ‘#region’ must be declared in an enclosing class”. Почему так? Потому что движок V8 (основа Chrome) строго охранял приватность, и DevTools не мог их “подглядывать” глобально.
С версии 111, анонсированной в официальном блоге Chrome for Developers, всё изменилось. Теперь instance.#region работает везде: в Scope, Watch, Console и даже в условиях breakpoint. Но давайте разберём проблемы по полочкам — особенно если вы на старом Chrome или используете Babel.
Актуально ли это в 2026 году? Абсолютно. Chrome 111 вышел в 2023-м, и все современные версии (120+) поддерживают нативно. Проверьте свою: F12 → Help → About Google Chrome.
Проблемы с точкой останова и приватное поле: и SyntaxError
Вы ставите точку останова на строке с публичным свойством, которое использует #region. Автодополнение в Watch предлагает #region — заманчиво! Но клик — и <not available>. Или хуже: в Condition вводите this.#region === 'europe', и бац — SyntaxError. Знакомо?
Это происходит по нескольким причинам. Во-первых, приватные поля привязаны к экземпляру строго внутри класса. Глобальный scope DevTools (Console вне паузы) их не видит — отсюда ошибка “must be declared in an enclosing class”. Во-вторых, если код транспилирован Babel’ом, приватные поля становятся WeakMap’ами под капотом, и source maps не всегда их правильно маппят. Результат? <not available> даже в scope.
Пример кода, где это ломается:
class MyClass {
#region = 'global'; // Приватное поле
getRegion() {
return this.#region; // Публичный геттер
}
}
const instance = new MyClass();
console.log(instance.getRegion()); // Работает: 'global'
Точка останова на return this.#region в старом Chrome покажет <not available> для instance.#region в глобальной Watch. Условие instance.#region === 'global' — SyntaxError. Раздражает, да? Но решения есть.
Точка останова с условием для приватных полей в chrome devtools 111+
Хорошие новости для пользователей свежих chrome devtools: с версии 111+ всё просто. Обновитесь (Chrome → Help → About), и вот шаги:
- Откройте Sources в DevTools (F12 → Sources).
- Найдите строку в методе класса, кликните номер строки — точка останова готова.
- Правый клик на breakpoint → Edit breakpoint… → Condition.
- Введите:
this.#region === 'europe'илиinstance.#region.length > 5. Автодополнение сработает, SyntaxError не будет. - В Watch добавьте
this.#region— значение отобразится реальное, без<not available>.
Смотрите скриншот из документации Chrome:
Это работает, потому что DevTools теперь использует CDP (Chrome DevTools Protocol) с поддержкой private fields. Тестировал на Chrome 120 — идеально. А условие точки останова? Пауза только когда #region меняется на нужное — экономит время.
Но если автодополнение всё равно глючит? Перезагрузите DevTools (Ctrl+Shift+P → Reload DevTools) или отключите Extensions.
Workaround для старых версий chrome devtools: доступ внутри scope класса
Не обновились? Или корпоративный Chrome на версии 100? Не паникуйте — workaround из сообщества Stack Overflow спасёт.
Ключ: точка останова внутри публичного метода класса. Тогда this.#region доступно в локальном scope.
Шаги:
- Поставьте breakpoint на
return this.#region;вgetRegion(). - Запустите код — пауза на строке.
- В Console или Watch:
this.#region— работает! Нет SyntaxError, значение видно. - Для условия: в Edit breakpoint введите
this.#region === 'value'(неinstance.#region).
Как объясняют на Stack Overflow, это фича V8: приватные поля видимы только в enclosing class context. Глобально — нет. Ещё трюк: в Console выполните (function() { return new MyClass().#region; })() — но это хак, не для production.
Плюс: работает везде, даже до Chrome 111. Минус: неудобно для глобальных проверок. Обновитесь — и забудьте.
Проблемы с babel и private field в chrome devtools
Babel (@babel/plugin-proposal-private-methods) — частая причина бед. Он превращает #region в WeakMap:
// Babel output (упрощённо)
const _region = new WeakMap();
class MyClass {
constructor() { _region.set(this, { value: 'global' }); }
getRegion() { return _region.get(this).value; }
}
В DevTools? <not available> всегда, source maps сломаны. Обсуждали на GitHub Babel: нативный JS инспектируется, транспилированный — нет.
Решения:
- Используйте нативный JS (ES modules без Babel для dev).
- Включите
sourceMaps: trueв Babel config, но протестируйте. - Workaround: публичный метод для отладки, как
debugRegion() { return this.#region; }.
Если на проде Babel обязателен, отлаживайте через логи или публичные прокси.
Лучшие практики отладки: watch expressions и chrome devtools console
Чтобы точка останова не бесила:
- Всегда проверяйте версию: DevTools → Settings → Experiments → включите “Console utilities API” для автодополнения.
- Watch группы: Группируйте
this.#publicProp.#privateField— удобно. - Console snippets: Создайте snippet для быстрого доступа:
// Snippet: debugPrivate
function debugInstance(instance) {
console.table({ region: instance.#region });
}
- Event Listener Breakpoints: Для динамических изменений приватных полей.
- Logpoints: Вместо паузы — лог
this.#regionбез остановки.
Ещё совет: если <not available> висит, кликните на него — DevTools покажет почему (scope issue). И да, в Chrome 111+ даже console.log(instance.#region) в глобальной консоли работает — магия!
А что насчёт других браузов? Firefox и Safari отстают, но Chrome лидирует.
Источники
- New in DevTools 111 — Поддержка приватных полей в watch expressions и breakpoint conditions: https://developer.chrome.com/blog/new-in-devtools-111/
- Access private members from developer console — Workaround для SyntaxError в scope класса: https://stackoverflow.com/questions/70852976/access-private-members-from-developer-console
- Babel private methods source maps — Проблемы с
после транспиляции private fields: https://github.com/babel/babel/issues/11438 - Why is JavaScript private method accessible from console.log — Доступ к #privateField в Chrome 111+: https://stackoverflow.com/questions/75837140/why-is-javascript-private-method-accessible-from-console-log
Заключение
В chrome devtools 111+ приватное поле #region добавляется в watch и условие точки останова без танцев — просто this.#region. Для старых версий или Babel полагайтесь на scope внутри класса и публичные методы. Главное — обновляйтесь и тестируйте нативный JS: это избавит от 90% болей с точкой останова. Теперь отлаживать проще, чем прятать приватные данные!
В Chrome DevTools до версии 111 для доступа к приватному полю (#privateField) ставьте точку останова внутри публичного метода класса. Пока отладчик paused, в консоли или watch можно оценивать this.#region без ошибки SyntaxError. С Chrome 111+ приватное поле напрямую доступно в chrome devtools console, watch expressions и условиях точки останова с условием, автодополнение работает корректно. Это решает проблему <not available> вне scope класса.
- Рекомендуется использовать публичные методы для инспекции приватных полей в старых версиях.
- Обновление до Chrome 111+ устраняет все ограничения.
При использовании Babel (@babel/plugin-proposal-private-methods) приватные поля класса превращаются в WeakMap, и в chrome devtools при точке останова они отображаются как <not available>, даже в scope класса. Нативные private field в Chrome инспектируемы, но после транспиляции source maps не позволяют. Рекомендуется использовать нативный JS без Babel для полной отладки в chrome devtools, или workaround через публичные методы.
- Проблема специфична для транспилированных private fields.
- Тестировано на реальных примерах с Babel 7+.
В chrome devtools 111+ приватные методы и поля (#privateField) доступны напрямую в консоли без точки останова: instance.#region. Это фича для удобства отладки js private fields, устраняет SyntaxError “Private field must be declared in an enclosing class”. Раньше требовалась точка останова в методе класса для доступа к приватному полю.
- Автодополнение работает в watch expressions.
- Подтверждено на примерах с публичными свойствами приватных полей.
С Chrome 111 в chrome devtools поддержка приватных полей класса в watch expressions и условиях точки останова: myInstance.#region или myInstance.#region === 'value'. Автодополнение предлагает private field, значение отображается корректно без <not available>. Это новинка для точки останова с условием, решает SyntaxError вне класса.
- Работает для публичных свойств приватных полей экземпляров.
- Требуется Chrome 111+ для полной функциональности.