posso desativar a otimização, para que as variáveis ​​do escopo dos fechamentos não sejam "otimizadas"

11

Como subproduto da otimização de código feita por navegadores modernos, durante a depuração, você não pode "ver" todas as variáveis ​​que "de fato" estão no escopo. Isso é bem conhecido e foi abordado em uma pergunta anterior aqui no SO . Esse recurso, embora certamente útil na produção me chateie bastante durante o desenvolvimento, me deixa mais lento (isso deve ser óbvio).

Agora, minha pergunta é: existe alguma maneira de desativar esse comportamento? Posso editar algum arquivo de configuração, ou existe um plug-in do navegador, ou talvez haja uma "versão de compilação especial para desenvolvedores" do executável do navegador? Adoro digitar meu código no console imediatamente quando estou escrevendo um novo código, então isso está realmente me incomodando.

visualSummaryIffalseConsoleLog

ATUALIZAÇÃO / EDIÇÃO

Aqui está uma solução parcial, creditada a Paul1365972.

Você precisa iniciar o navegador chrome na linha de comando, com opções especiais, como:

  1. Feche completamente o Chrome
  2. Execute o Chrome a partir do console com "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe" --js-flags="--allow-natives-syntax" o Windows para outros SOs semelhantes.
  3. Abra o console do desenvolvedor e execute "%GetHeapUsage()". Se você iniciou o Chrome corretamente com a opção, um número será registrado no console; caso contrário, você receberá um erro de sintaxe.

Com esse sinalizador de linha de comando, você pode 'conversar com o mecanismo V8' com comandos iniciados por %, que são erros de sintaxe no JavaScript comum. Uma lista dos comandos V8 disponíveis desse tipo foi dada na resposta de Paulo .

Existe %NeverOptimizeFunction()nessa lista, que é algo que parecia com o que eu precisaria chamar e terminar com isso. Infelizmente, essa função não faz o que eu esperava, como demonstrado na próxima captura de tela.

lorem ainda não definido

(((O outro link da resposta de Paul (módulo de nó nativo da v8)) não é importante para nós aqui neste contexto. Tudo o que faz é envolver uma linha em torno das chamadas da função "%" para que o código não falhe navegadores que não são v8.)))

(((Lembro-me de uma época em que isso funcionou (quando essa otimização ainda não foi inventada / implementada)). Não sei há quanto tempo. Dez anos? 15 anos? Algo assim. Qual foi a última versão do Chrome (se qualquer) e qual foi a última versão do firefox (mais segura aqui que existe) onde você poderia fazer? Não receberá a recompensa, mas receberá um voto positivo, se você souber e publicá-la como resposta .)))

A SOLUÇÃO

OBRIGADO PETR SRNICEK

correção hacky

NOVA PERGUNTA

Embora a solução de Petr ajude bastante, ela não é perfeita. Como essa pergunta está ficando muito longa, publiquei uma nova pergunta sobre como a solução de Petr pode ser aprimorada. (É claro que eu poderia editar esta pergunta aqui, mas isso pareceria "não histórico", se você entende o que quero dizer.)

mathheadinclouds
fonte
conseqüências não intencionais, capítulo décimo mil e um. essa otimização tem um efeito negativo no meu estilo de codificação. Encontro-me usando o loop for antiquado (em vez de .map, .forEach, .reduce) mais do que usaria de outra maneira, apenas para evitar encontrar esse problema.
Mathheadinclouds 18/11/19
A v8-nativesbiblioteca apenas envolve as chamadas% importantes no código em uma biblioteca simples que devem estar noopsem um navegador ou nó que não foi iniciado na bandeira especial --allow-nativos-sintaxe ..
Nathanael
Fiz alguns testes, a função 'bodyOnLoad' não é otimizada; portanto, usar os comandos internos para tentar forçá-lo a des otimizar não faz nada.
Nathanael
@ Nathanael: A ligação importante é que %NeverOptimizeFunction(foo)eu também a chamei de bodyOnload, "só porque", pensando "bem, não vai doer". A questão é que fooNÃO é desoptimizado da maneira que eu esperava. Variável loremé invisível. Digamos que eu queira escrever o código que deve entrar na função foo. Em vez de digitá-lo no meu editor de texto, digito-o no console de desenvolvimento (enquanto o depurador está no foo), ver se ele faz o que eu quero e depois copio / colo do console para o meu editor de texto. É assim que eu amo trabalhar. E não pode. Por causa da otimização. Pegue?
mathheadinclouds
11
Passei várias experiências com vários --js-flags(incluindo vários relacionados ao TurboFan ), bem como com vários comandos nativos do V8 antes de Paul1365972 postar sua resposta, mas não consegui atingir o comportamento desejado. Acredito que essa abordagem possa ser um beco sem saída. Pode valer a pena adicionar uma [v8]tag a esta pergunta. Alguém com um entendimento profundo do funcionamento interno do V8 pode ser capaz de esclarecer se esse é o caminho a seguir ou talvez apontá-lo na direção correta.
Petr Srníček

Respostas:

2

Você pode ter acesso a todas as variáveis envolvendo a declaração depurador em um eval como este: eval("debugger;");. Essa solução hacky adiciona outra função anônima à pilha de chamadas e, obviamente, não serve para pontos de interrupção definidos manualmente no DevTools.

Essa não parece ser uma solução muito boa, mas como é a única que alcança o comportamento pretendido até agora, estou postando-o como resposta.

Petr Srníček
fonte
me surpreende que isso funcione. Sabe, tentei digitar eval ("lorem") e isso deu o mesmo erro "lorem não está definido". Não faz muito sentido para mim que digitar eval ("lorem") no console (enquanto na instrução debugger na função foo) deve fazer algo diferente do que eval ("debugger") está fazendo - espere, imprima "ipsum" para o console. Mas eles são muito diferentes. Estranho.
mathheadinclouds
Esse é um trabalho interessante. É um pouco hacky, pois você não pode sair da instrução depurador (você só precisa alternar manualmente para o arquivo de origem), caso contrário, perde a pilha inteira e retorna à função que chamou eval; deixando a pilha reduzida ausente no outro contexto.
Nathanael
pode-se modificar esse truque assim: em vez de eval ("depurador"), coloque apenas eval ("") - mas muitos deles, distribuídos por todo o código, em todos os lugares onde você acha que pode querer um 'ponto de interrupção estendido'. Você pode então definir um ponto de interrupção (com as ferramentas de desenvolvimento) onde está uma dessas instruções eval ('') e, quando você parar por aí, "entra". Estou pensando em escrever um pequeno transpiler (palavra grande para uma coisa pequena que estou fazendo) colocando essas instruções no início de cada função. stackoverflow.com/questions/59159996/…
mathheadinclouds
Eu apenas tentei substituir eval ("depurador") por eval (); depurador e obteve resultados diferentes, dependendo do uso do Firefox ou Chrome. i.stack.imgur.com/wy5WT.png
mathheadinclouds
3

O Google Chrome usa o V8 JS-Engine, você pode ativar chamadas nativas para ele com o sinalizador --allow-natives-syntax, isso expõe muitas funções úteis de depuração (lista completa aqui ) como a que você está procurando:% NeverOptimizeFunction () . Sem esse sinalizador, essas chamadas seriam sintaxe ilegal; portanto, tenha cuidado ao implantar (ou usar a biblioteca v8-Natives ).

Para habilitar esse recurso, basta abrir o chrome com --js-flags = "- allow-natives-syntax" (use isso apenas para depuração de sites confiáveis, pois isso pode dar ao código js não confiável acesso a coisas que você realmente não deseja. Ter acesso à).

Paul1365972
fonte
obrigado. Por favor, leia minha pergunta atualizada. Parece bastante provável que você tenha a solução aqui, mas preciso de mais alguns esclarecimentos para que ela funcione. Se isso funcionar, você com certeza merece a recompensa.
mathheadinclouds
tl; dr use --js-flags = "- allow-natives-syntax" em vez disso. Para ativar o recurso que o V8 JS-Engine precisa ser iniciado com o sinalizador --allow-natives-syntax, no entanto, você não pode iniciá-lo diretamente, este é um trabalho de cromos. Então você precisa dizer ao chrome para iniciar o mecanismo com a bandeira, como você faz isso? Basta passar a flag de mecanismo mencionada via --js-flags = <sua flag aqui> para o chrome.
Paul1365972
Não. Apenas tentei mais uma vez, ser o lado seguro. Eu tentei várias --allow-natives-syntaxe --js-flags="--allow-natives-syntax"várias vezes como "a coisa que digito após 'chrome' no console do sistema operacional". Se eu não tivesse tentado isso sozinho, também pensaria que um erro de digitação é a explicação mais provável. Eu fiz outra captura de tela. i.stack.imgur.com/7cpPP.png Sabe de um erro de digitação? Por favor, me dê uma resposta honesta: você acabou de "ler e entender o artigo" (para ser claro, nada de errado nisso, se você não reivindicar mais), ou realmente tentou tudo isso em sua máquina? thx
mathheadinclouds
apenas um palpite: será que eu não inicio o executável chrome com essa opção, mas compilo as fontes C ++ (ou o que for) do chrome com essa opção?
mathheadinclouds
11
Isso é estranho, eu apenas testei e funcionou bem, sem necessidade de compilação. Vou escrever exatamente o que fiz, para que não haja mal-entendidos. 1. Feche o Chrome completamente 2. Execute o Chrome no console com "C: / Arquivos de Programas (x86) /Google/Chrome/Application/chrome.exe" --js-flags = "- allow-natives-syntax" 3. Abra console do desenvolvedor e executar "% GetHeapUsage ()" para testar se tudo está funcionando
Paul1365972
0

Eu realmente espero que esta pergunta tenha uma resposta REAL. O que se segue não é uma resposta real, é improvisado. Eu escrevi uma ferramenta auxiliar com a qual você pode criar código auxiliar estúpido do formulário if (false) { console.log(variables, from, closures); }(veja a captura de tela em questão) usando análise estática - você cola no seu código, a instrução estúpida é criada, você pode copiá-la e depois não precisa para digitá-lo. Não sei se isso ajuda muito, pois todas essas cópias e colagens também levam tempo, mas foi o que consegui.

captura de tela

violino

mathheadinclouds
fonte