Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

487
Visualizações
¿Por qué el depurador de Chrome cree que la variable local cerrada no está definida?

Con este código:

 function baz() { var x = "foo"; function bar() { debugger; }; bar(); } baz();

Obtengo este resultado inesperado:

ingrese la descripción de la imagen aquí

Cuando cambio el código:

 function baz() { var x = "foo"; function bar() { x; debugger; }; bar(); }

Obtengo el resultado esperado:

ingrese la descripción de la imagen aquí

Además, si hay alguna llamada a eval dentro de la función interna, puedo acceder a mi variable como quiero (no importa lo que pase a eval ).

Mientras tanto, las herramientas de desarrollo de Firefox dan el comportamiento esperado en ambas circunstancias.

¿Qué pasa con Chrome que el depurador se comporta de manera menos conveniente que Firefox? He observado este comportamiento durante algún tiempo, hasta la versión 41.0.2272.43 beta (64 bits) inclusive.

¿Es que el motor javascript de Chrome "aplana" las funciones cuando puede?

Curiosamente, si agrego una segunda variable a la que se hace referencia en la función interna, la variable x aún no está definida.

Entiendo que a menudo hay peculiaridades con alcance y definición de variable cuando se usa un depurador interactivo, pero me parece que, según la especificación del idioma, debería haber una "mejor" solución para estas peculiaridades. Así que tengo mucha curiosidad si esto se debe a que Chrome se optimizó más que Firefox. Y también si estas optimizaciones se pueden deshabilitar fácilmente durante el desarrollo (¿tal vez deberían deshabilitarse cuando las herramientas de desarrollo están abiertas?).

Además, puedo reproducir esto con puntos de interrupción, así como con la declaración del debugger .

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Encontré un informe de problemas de v8 que es precisamente sobre lo que está preguntando.

Ahora, para resumir lo que se dice en ese informe de problemas... v8 puede almacenar las variables que son locales para una función en la pila o en un objeto de "contexto" que vive en el montón. Asignará variables locales en la pila siempre que la función no contenga ninguna función interna que se refiera a ellas. Es una optimización . Si alguna función interna hace referencia a una variable local, esta variable se colocará en un objeto de contexto (es decir, en el montón en lugar de en la pila). El caso de eval es especial: si es llamado por una función interna, todas las variables locales se colocan en el objeto de contexto.

El motivo del objeto de contexto es que, en general, puede devolver una función interna desde la externa y luego la pila que existía mientras se ejecutaba la función externa ya no estará disponible. Entonces, cualquier cosa a la que acceda la función interna tiene que sobrevivir a la función externa y vivir en el montón en lugar de en la pila.

El depurador no puede inspeccionar aquellas variables que están en la pila. Con respecto al problema encontrado en la depuración, un miembro del proyecto dice :

La única solución que se me ocurrió es que cada vez que devtools esté activado, retiraríamos todo el código y lo volveríamos a compilar con una asignación de contexto forzada. Sin embargo, eso haría retroceder drásticamente el rendimiento con devtools habilitados.

Aquí hay un ejemplo de "si alguna función interna se refiere a la variable, colóquela en un objeto de contexto". Si ejecuta esto, podrá acceder a x en la declaración del debugger , aunque x solo se usa en la función foo , ¡ que nunca se llama !

 function baz() { var x = "x value"; var z = "z value"; function foo () { console.log(x); } function bar() { debugger; }; bar(); } baz();
over 4 years ago · Santiago Trujillo Relatório

0

Como dijo @Louis, fue causado por optimizaciones v8. Puede atravesar la pila de llamadas para enmarcar donde esta variable es visible:

llamar1 llamar2

O reemplace debugger con

 eval('debugger');

eval abandonará el fragmento actual

over 4 years ago · Santiago Trujillo Relatório

0

También he notado esto en nodejs. Creo (y admito que esto es solo una conjetura) que cuando se compila el código, si x no aparece dentro de bar , no hace que x esté disponible dentro del alcance de bar . Esto probablemente lo hace un poco más eficiente; el problema es que alguien olvidó (o no le importó) que incluso si no hay x en bar , puede decidir ejecutar el depurador y, por lo tanto, aún necesita acceder a x desde dentro de bar .

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda