Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

486
Views
¿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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!