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

200
Views
¿Cómo funciona esta elevación con alcance de bloque?

me han hecho una pregunta

 { function foo() { console.log('A'); } foo(); foo = 1; function foo() { console.log('B'); } foo = 2; console.log(foo); } console.log(foo);

¿Por qué la tercera salida es 1 en lugar de 2 ?


No debe crearse foo con alcance de bloque, ya que no hay ni let ni const en ese bloque. Pero la segunda salida de foo es 2 significa que, de hecho, se ha creado otra referencia de foo .

Que esta pasando?

PD: estoy usando la Version 89.0.4389.90 (Official Build) (x86_64) .

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Este es un análisis de lo que sucede con un depurador en Node.js. No explica por qué sucede esto.

Hay 3 ámbitos involucrados: ámbito local, ámbito global y ámbito de bloque.

Hice el mismo análisis en un navegador Chrome. El comportamiento fue similar con la única diferencia de que no hay alcance local y en lugar del alcance local se utilizó el alcance global.

El código

 { foo = 1; foo = 2; console.log(foo); } console.log(foo);

crea una variable en ámbito global y establece dos valores diferentes para esa variable. en este codigo

 { function foo() { } foo = 1; foo = 2; console.log(foo); } console.log(foo);

la function foo() { } crea una variable foo en el alcance del bloque y una variable foo en el alcance local (alcance global en Chrome). Dado que existe una variable en el alcance del bloque foo = 1; establece un valor para la variable existente en el ámbito del bloque y no crea una variable en el ámbito global. foo = 2; establece un valor diferente para la misma variable. La primera console.log(foo); imprime 2 desde el alcance del bloque y el segundo console.log(foo); imprime f foo() { } desde el alcance local (alcance global en Chrome).

en este codigo

 { foo = 1; function foo() { } foo = 2; console.log(foo); } console.log(foo);

la función de declaración de function foo() { } se eleva y crea una variable foo en el ámbito del bloque con el valor f foo() {} y una variable foo en el ámbito local (alcance global en Chrome) con el valor undefined . La línea foo = 1; establece ambas variables en 1 . La línea foo = 2; establece la variable en el alcance del bloque en 2 . La primera console.log(foo); imprime 2 desde el alcance del bloque y el segundo console.log(foo); imprime 1 desde el alcance local (alcance global en Chrome).

en este codigo

 { function foo() { } foo = 1; function foo() { } foo = 2; console.log(foo); } console.log(foo);

la función de declaración de function foo() { } crea una variable foo en el alcance del bloque con el valor f foo() {} y una variable foo en el alcance local (alcance global en Chrome) con el valor f foo() {} . La línea foo = 1; establece ambas variables en 1 . La línea foo = 2; establece la variable en el alcance del bloque en 2 . La primera console.log(foo); imprime 2 desde el alcance del bloque y el segundo console.log(foo); imprime 1 desde el alcance local (alcance global en Chrome).

over 4 years ago · Santiago Trujillo Report

0


De acuerdo con la semántica de compatibilidad web en el lugar de la declaración de la función, el valor de la variable de ámbito bloqueado está vinculado al ámbito externo². Este código es equivalente a:

 let outerFoo; // the functions create a binding outside of the scope { let innerFoo; // but also inside // due to hoisting, functions get bound before any code get's executed: innerFoo = function foo() { console.log('A'); }; innerFoo = function foo() { console.log('B'); }; // At the place of the function declaration, the variable leaves the scope /* function foo() { console.log('A'); } */ outerFoo = innerFoo; innerFoo(); innerFoo = 1; // this also applies to the second declaration /* function foo() { console.log('B'); } */ outerFoo = innerFoo; innerFoo = 2; console.log(innerFoo); } console.log(outerFoo);

²Así es básicamente como lo describe la especificación:

 When the FunctionDeclaration f is evaluated, perform the following steps in place of the FunctionDeclaration Evaluation algorithm provided in 15.2.6: a. Let fenv be the running execution context's VariableEnvironment. b. Let benv be the running execution context's LexicalEnvironment. c. Let fobj be ! benv.GetBindingValue(F, false). d. Perform ! fenv.SetMutableBinding(F, fobj, false).

La especificación establece además:

Antes de ECMAScript 2015, la especificación de ECMAScript no definía la ocurrencia de una declaración de función como un elemento de la lista de declaraciones de una declaración de bloque. Sin embargo, el soporte para esa forma de FunctionDeclaration era una extensión permitida y la mayoría de las implementaciones de ECMAScript alojadas en el navegador lo permitían. Desafortunadamente, la semántica de tales declaraciones difiere entre esas implementaciones. Debido a estas diferencias semánticas, el código ECMAScript web existente que usa declaraciones de función de nivel de bloque solo es portátil entre implementaciones de navegador si el uso solo depende de la intersección semántica de todas las implementaciones de navegador para tales declaraciones.

Por lo tanto, es probable que Safari lo esté haciendo como siempre lo hizo, mientras que Chrome (y Firefox) siguen la especificación.

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!