можно отключить оптимизацию, чтобы переменные в области видимости из замыканий не «оптимизировались»

11

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

Теперь мой вопрос: есть ли способ отключить это поведение? Могу ли я отредактировать какой-либо файл конфигурации, или есть плагин для браузера, или, может быть, существует «специальная версия сборки для разработчиков» исполняемого файла браузера? Мне нравится вводить свой код в консоль сразу, когда я пишу новый код, так что это действительно беспокоит меня.

visualSummaryIffalseConsoleLog

ОБНОВЛЕНИЕ / РЕДАКТИРОВАНИЕ

Вот частичное решение, кредит Paul1365972.

Вы должны запустить браузер Chrome из командной строки со специальными параметрами, например:

  1. Закройте Chrome полностью
  2. Запустите Chrome из консоли с "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe" --js-flags="--allow-natives-syntax" Windows аналогичной ОС.
  3. Откройте консоль разработчика и выполните "%GetHeapUsage()". Если вы правильно запустили Chrome с этой опцией, в консоль войдет номер, в противном случае вы получите синтаксическую ошибку.

С этим флагом командной строки вы можете «разговаривать с V8» движком, начиная с команд %, которые являются синтаксическими ошибками в простом JavaScript. Список доступных команд V8 такого рода был дан в ответе Пола .

В %NeverOptimizeFunction()этом списке есть что-то, что выглядело так, как будто мне просто нужно позвонить и покончить с этим. К сожалению, эта функция не делает то, на что я рассчитывал, как показано на следующем скриншоте.

Lorem до сих пор не определено

((( Другая ссылка из ответа Пола (модуль узла v8-natives) здесь не имеет значения для нас в этом контексте. Все, что он делает - это оборачивает однострочники вокруг вызовов функции "%", чтобы код не падал браузеры которые не v8.)))

(((Я помню время, когда это работало (когда эта оптимизация еще не была изобретена / реализована). Я не знаю, как давно. Десять лет? 15 лет? Что-то в этом роде. Какой была последняя версия Chrome (если любая) и какой была последняя версия Firefox (более уверенная в том, что она существует), где вы могли это сделать? Она не принесет вам награду, но вы получите повышение, если вам это случится, и опубликуйте ее как ответ .)))

РЕШЕНИЕ

СПАСИБО ПЕТР СРНИЦЕК

хакерское исправление

НОВЫЙ ВОПРОС

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

mathheadinclouds
источник
непредвиденные последствия, глава десятая тысяча. эта оптимизация отрицательно влияет на мой стиль кодирования. Я обнаружил, что использую устаревший цикл for (вместо .map, .forEach, .reduce) больше, чем в противном случае, просто чтобы избежать этой проблемы.
mathheadinclouds
v8-nativesБиблиотека просто оборачивает важные% вызовов в коде в простых библиотеках , которые должны быть noopsв браузере или узле , который не был запущен в специальном флаге --allow-туземцы-синтаксического ..
Нафанаил
Я провел несколько тестов, функция bodyOnLoad не оптимизирована; поэтому использование внутренних команд, чтобы попытаться заставить его де-оптимизировать, ничего не делает.
Натанаэль
@Nathanael: Важным вызовом является %NeverOptimizeFunction(foo)то, что я просто назвал его также для bodyOnload, «просто потому, что», думая: «Ну, это не повредит». Проблема в том, что fooНЕ деоптимизирован так, как я надеялся. Переменная loremневидима. Допустим, я хочу написать некоторый код для перехода в функцию foo. Вместо того, чтобы печатать его в моем текстовом редакторе, я набираю его в консоли разработчика (пока отладчик сидит на foo), проверяю, выполняет ли он то, что я хочу, а затем копирую / вставляю его из консоли в мой текстовый редактор. Вот так я люблю работать. И не могу. Из-за оптимизации. Возьми?
Математические облака
1
Я провел несколько наших экспериментов с различными --js-flags(включая несколько связанных с TurboFan ), а также с несколькими собственными командами V8, прежде чем Paul1365972 опубликовал свой ответ, но я не смог добиться желаемого поведения. Я считаю, что такой подход может оказаться тупиком. Возможно, стоит добавить [v8]тег к этому вопросу. Кто-то с глубоким пониманием внутренней работы V8 может быть в состоянии уточнить, идет ли этот путь или, возможно, укажет вам правильное направление.
Петр Срничек

Ответы:

2

Вы можете получить доступ ко всем переменным, поместив оператор отладчика в eval, например так: eval("debugger;"); . Это хакерское решение добавляет еще одну анонимную функцию в стек вызовов и, очевидно, бесполезно для точек останова, которые устанавливаются вручную в DevTools.

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

Петр Срничек
источник
это как-то удивляет меня, что это работает. Вы знаете, я пытался набрать eval ("lorem"), и это вывело ту же ошибку "lorem is notfined". Для меня не имеет особого смысла, что ввод eval ("lorem") на консоли (в то время как в операторе отладчика в функции foo) должен делать что-то отличное от того, что делает eval ("отладчик") - ожидайте, напечатайте "ipsum" на консоль. Но они очень разные. Странный.
mathheadinclouds
Это интересная работа вокруг. Это немного странно, так как вы не можете выйти из оператора отладчика (вам просто нужно вручную переключиться на исходный файл), иначе вы потеряете весь стек и вернетесь к функции, которая вызвала eval; оставляя вам уменьшенный стек без другого контекста.
Натанаэль
можно изменить этот трюк следующим образом: вместо eval («отладчик»), просто установите eval («») - но многие из них распределены по всему коду везде, где, как вы думаете, может потребоваться «расширенная точка останова». Затем вы можете установить точку останова (с помощью инструментов dev), где находится одно из этих утверждений eval (''), и как только вы остановитесь там, вы сделаете "шаг в". Я собираюсь написать небольшой транспортер (большое слово для небольшой вещи, которую я делаю), помещая эти операторы в начале каждой функции. stackoverflow.com/questions/59159996/…
mathheadinclouds
Я просто попытался заменить eval ("отладчик") на eval (); отладчик, и получил разные результаты, в зависимости от использования Firefox или Chrome. i.stack.imgur.com/wy5WT.png
mathheadinclouds
3

Google Chrome использует V8 JS-Engine, вы можете включить собственные вызовы к нему с помощью флага --allow-natives-syntax, который предоставляет множество полезных функций отладки (полный список здесь ), например ту, которую вы ищете:% NeverOptimizeFunction () , Без этого флага эти вызовы были бы недопустимым синтаксисом, поэтому будьте осторожны при развертывании (или используйте библиотеку V8-Natives ).

Чтобы включить эту функцию, просто откройте chrome с --js-flags = "- allow-natives-syntax" (используйте это только для отладки доверенных веб-сайтов, так как это может дать недоверенному коду js доступ к вещам, которые вы на самом деле не хотите иметь доступ к).

Paul1365972
источник
благодарю вас. Пожалуйста, прочитайте мой обновленный вопрос. Кажется вполне вероятным, что у вас есть решение здесь, но мне нужно больше разъяснений, чтобы оно заработало. Если это работает, вы, безусловно, заслуживаете награды.
Математические облака
tl; dr вместо этого использовать --js-flags = "- allow-natives-syntax". Чтобы включить эту функцию, JS-Engine V8 должен быть запущен с флагом --allow-natives-syntax, однако вы не можете запустить его напрямую, это задание chromes. Итак, вы должны сказать chrome запустить двигатель с флагом, как вы это делаете? Просто передайте упомянутый флаг движка через --js-flags = <ваш флаг здесь> в chrome.
Paul1365972
нет. Просто попробовал это еще раз, чтобы быть в безопасности. Я пробовал и то --allow-natives-syntaxи другое --js-flags="--allow-natives-syntax"несколько раз как «то, что я набираю после« chrome »в консоли операционной системы». Если бы я не попробовал все это сам, я бы тоже подумал, что опечатка - наиболее вероятное объяснение. Я сделал еще один скриншот. i.stack.imgur.com/7cpPP.png Видите опечатку? Пожалуйста, дайте мне честный ответ: вы просто «прочитали и поняли статью» (чтобы быть понятным, в этом нет ничего плохого, если вы не требуете больше), или вы действительно все это попробовали на своей машине? thx
mathheadinclouds
просто предположение: может ли быть так, что я не запускаю исполняемый файл chrome с этой опцией, но я скомпилирую исходные коды chrome C ++ (или что-то еще) с этой опцией?
mathheadinclouds
1
Это странно, я только что проверил его, и он работал нормально, компиляция не требуется. Я просто напишу точно, что я сделал, чтобы не было недопонимания. 1. Полностью закройте Chrome 2. Запустите Chrome из консоли с помощью «C: / Program Files (x86) /Google/Chrome/Application/chrome.exe» --js-flags = "- allow-natives-syntax" 3. Откройте консоль разработчика и выполните «% GetHeapUsage ()», чтобы проверить, все ли работает
Paul1365972
0

Я действительно надеюсь, что этот вопрос имеет РЕАЛЬНЫЙ ответ. То, что следует, не реальный ответ, это временное решение. Я написал вспомогательный инструмент, с помощью которого вы можете создать глупый вспомогательный код видаif (false) { console.log(variables, from, closures); } (см. Снимок экрана) с помощью статического анализа - вы вставляете в свой код, создается глупый оператор, вы можете скопировать его, тогда вам не нужно набрать его. Я не знаю, поможет ли это много, так как копирование и вставка также требуют времени, но это то, что я получил.

Скриншот

играть на скрипке

mathheadinclouds
источник