Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

248
Vistas
ReferenceError: can't access lexical declaration 'Foo' before initialization

Running the following code:

<!doctype html>
<html>
<head>
  <meta charset="UTF-8">
</head>
<body>
<script>
  main()
  class Foo { }
  function main() { Foo() }
</script>
</body>
</html>

generates ReferenceError: can't access lexical declaration 'Foo' before initialization (on Firefox 91.5.1esr, anyway).

A simple fix is to move the class definition up a line. Replacing class Foo with function Foo() will also eliminate the error message. Changing Foo() to new Foo(), does not help: the error remains.

Question: Is there a reference to the standards, and/or a clear description, explaining this behavior?

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

A class is a ClassDeclaration in the spec. This is classified as a DeclarationPart, which is classified as a StatementListItem for the purposes of LexicallyScopedDeclarations.

When a block or function is evaluated initially (before the code in the block actually starts running), it will do something like:

33. Let lexDeclarations be the LexicallyScopedDeclarations of code.
34. For each element d of lexDeclarations, do
  a. NOTE: A lexically declared name cannot be the same as a function/generator declaration, formal parameter, or a var name. Lexically declared names are only instantiated here but not initialized.
  b. For each element dn of the BoundNames of d, do
    i. If IsConstantDeclaration of d is true, then
      1. Perform ! lexEnv.CreateImmutableBinding(dn, true).
    ii. Else,
      1. Perform ! lexEnv.CreateMutableBinding(dn, false).

These LexicallyScopedDeclarations are identifiers created with ES6+ syntax, and exclude var. (Identifiers created with var are classified as varNames, or VarDeclaredNames, which go through a different process than steps 33-34 above.)

So, at the beginning of a block or function, class identifiers (and const and let identifiers) all have bindings that have been created in the environment, but have not been initialized in the environment. Initialization occurs when BindingClassDeclarationEvaluation runs, which does:

5. Perform ? InitializeBoundName(className, value, env).

This only happens when the engine is actually running the code inside the block or function and comes across class SomeClassName. (This is separate from the process referenced earlier, which is when the engine is only looking through the text of the block to get a list of identifiers that are declared inside.)


When a block is running, and you try to instantiate something with new, EvaluateNew runs, which does, among other things:

Let constructor be ? GetValue(ref).

which eventually runs GetBindingValue, which has:

2. If the binding for N in envRec is an uninitialized binding, throw a ReferenceError exception.

The binding only gets initialized when InitializeBoundName runs - that is, when the engine comes across the class declaration.

about 4 years ago · Juan Pablo Isaza Denunciar

0

A simple way to understand why this error happens involves understanding hoisting. Before execution, an interpreter (like a browser engine) will move all variables and functions to the top of the file, likely for ease of access. But more modern instances of variables and functions, such as classes and function expressions, might get hoisted to the top but without being initialized. This is why that although the class is found, it has no proper value assigned to it, even if empty, thus an error occurs.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda