---
title: "How Declarations are Collected for Instantiation?"
description: "Learn how JavaScript engines collect declaration information for instantiation, including global, function, and block contexts."
lang: "en"
tags: ["JavaScript", "ECMA-262"]
pubDate: 2024-06-20T00:00:00.000Z
---

To process the declaration instantiation, the engine needs things like `VarDeclaredNames`, `LexicallyDeclaredNames`, `VarScopedDeclarations`, and `LexicallyScopedDeclarations` in a piece of code.

In this article, we will see how this information is collected from the code according to the specification.

## Declaration

What is [`declaration`](https://262.ecma-international.org/13.0/index.html#prod-Declaration)? The declaration is one kind of ECMAScript statement. Here's all kinds of declarations listed in the specification:

```
14 ECMAScript Language: Statements and Declarations

Syntax

	Declaration[Yield, Await] :
		HoistableDeclaration[?Yield, ?Await, ~Default]
		ClassDeclaration[?Yield, ?Await, ~Default]
		LexicalDeclaration[+In, ?Yield, ?Await]

	HoistableDeclaration[Yield, Await, Default] :
		FunctionDeclaration[?Yield, ?Await, ?Default]
		GeneratorDeclaration[?Yield, ?Await, ?Default]
		AsyncFunctionDeclaration[?Yield, ?Await, ?Default]
		AsyncGeneratorDeclaration[?Yield, ?Await, ?Default]
```

## Global

### The information needed in [`GlobalDeclarationInstantiation(scriptBody, globalEnv)`](https://262.ecma-international.org/13.0/index.html#sec-globaldeclarationinstantiation):

- [LexicallyDeclaredNames](https://262.ecma-international.org/13.0/index.html#sec-static-semantics-lexicallydeclarednames) of `script`
- [LexicallyScopedDeclarations](https://262.ecma-international.org/13.0/index.html#sec-static-semantics-lexicallyscopeddeclarations) of `script`
- [VarDeclaredNames](https://262.ecma-international.org/13.0/index.html#sec-static-semantics-vardeclarednames) of `script`
- [VarScopedDeclarations](https://262.ecma-international.org/13.0/index.html#sec-static-semantics-varscopeddeclarations) of `script`

### How are `VarScopedDeclarations` collected from `scriptBody`?

In short, it collects top-level HoistableDeclarations (`function`), top-level VariableStatements (`var`), and block-nested VariableStatements.

```
Static Semantics: VarScopedDeclarations

 ScriptBody : StatementList
    1. Return TopLevelVarScopedDeclarations of StatementList.
```

```
Static Semantics: TopLevelVarScopedDeclarations

 StatementList : StatementList StatementListItem
    1. Let declarations1 be TopLevelVarScopedDeclarations of StatementList.
    2. Let declarations2 be TopLevelVarScopedDeclarations of StatementListItem.
    3. Return the list-concatenation of declarations1 and declarations2.

StatementListItem : Statement
    1. If Statement is Statement : LabelledStatement , return TopLevelVarScopedDeclarations of Statement.
    2. Return VarScopedDeclarations of Statement.

StatementListItem : Declaration
    1. If Declaration is Declaration : HoistableDeclaration , then
        a. Let declaration be DeclarationPart of HoistableDeclaration.
        b. Return « declaration ».
    2. Return a new empty List.
```

```
// implicit definition of chain productions
Static Semantics: VarScopedDeclarations

Statement : BlockStatement
    1. Return VarScopedDeclarations of BlockStatement.

BlockStatement : Block
    1. Return VarScopedDeclarations of Block.

Block : { StatementList }
    1. Return VarScopedDeclarations of StatementList.
```

About "implicit definition of chain productions," see: [What is the implicit definition of “chain productions”?](./introduction-to-ecma-262#addition-what-is-the-implicit-definition-of-chain-productions)

```
Static Semantics: VarScopedDeclarations

 StatementList : StatementList StatementListItem
    1. Let declarations1 be VarScopedDeclarations of StatementList.
    2. Let declarations2 be VarScopedDeclarations of StatementListItem.
    3. Return the list-concatenation of declarations1 and declarations2.

StatementListItem : Declaration
    1. Return a new empty List.

VariableDeclarationList : VariableDeclaration
    1. Return « VariableDeclaration ».
```

### How are `VarDeclaredNames` collected from `scriptBody`?

Same as `VarScopedDeclarations`.

### How are `LexicallyScopedDeclarations` collected from `scriptBody`?

In short, it collects top-level ClassDeclarations (`class`) and LexicalDeclarations (`let` and `const`).

```
Static Semantics: LexicallyScopedDeclarations
 ScriptBody : StatementList
    1. Return TopLevelLexicallyScopedDeclarations of StatementList.
```

```
Static Semantics: TopLevelLexicallyScopedDeclarations
 StatementList : StatementList StatementListItem

    1. Let declarations1 be TopLevelLexicallyScopedDeclarations of StatementList.
    2. Let declarations2 be TopLevelLexicallyScopedDeclarations of StatementListItem.
    3. Return the list-concatenation of declarations1 and declarations2.

StatementListItem : Statement

    1. Return a new empty List.

StatementListItem : Declaration

    1. If Declaration is Declaration : HoistableDeclaration , then
        a. Return a new empty List.
    2. Return « Declaration ».
```

```
14 ECMAScript Language: Statements and Declarations

Syntax

	Declaration[Yield, Await] :
		HoistableDeclaration[?Yield, ?Await, ~Default]
		ClassDeclaration[?Yield, ?Await, ~Default]
		LexicalDeclaration[+In, ?Yield, ?Await]

	HoistableDeclaration[Yield, Await, Default] :
		FunctionDeclaration[?Yield, ?Await, ?Default]
		GeneratorDeclaration[?Yield, ?Await, ?Default]
		AsyncFunctionDeclaration[?Yield, ?Await, ?Default]
		AsyncGeneratorDeclaration[?Yield, ?Await, ?Default]
```

### How are `LexicallyDeclaredNames` collected from `scriptBody`?

Same as `LexicallyScopedDeclarations`.

## Function

### The information needed in [`FunctionDeclarationInstantiation(functionObject, argumentsList)`](https://262.ecma-international.org/13.0/index.html#sec-functiondeclarationinstantiation)

- Let `code` be `functionObject.[[ECMAScriptCode]]`
  - [VarDeclaredNames](https://262.ecma-international.org/13.0/index.html#sec-static-semantics-vardeclarednames) of `code`
  - [VarScopedDeclarations](https://262.ecma-international.org/13.0/index.html#sec-static-semantics-varscopeddeclarations) of `code`
  - [LexicallyDeclaredNames](https://262.ecma-international.org/13.0/index.html#sec-static-semantics-lexicallydeclarednames) of `code`
  - [LexicallyScopedDeclarations](https://262.ecma-international.org/13.0/index.html#sec-static-semantics-lexicallyscopeddeclarations) of `code`
- Let `formals` be `functionObject.[[FormalParameters]]`
  - [BoundNames](https://262.ecma-international.org/13.0/index.html#sec-static-semantics-boundnames) of `formals`
  - [IteratorBindingInitialization](https://262.ecma-international.org/13.0/index.html#sec-runtime-semantics-iteratorbindinginitialization) of `formals` (initialized with `argumentsList`)

### How are `VarScopedDeclarations` collected from `functionObject.[[ECMAScriptCode]]`?

In short, it collects top-level HoistableDeclarations (`function`), top-level VariableStatements (`var`), and block-nested VariableStatements.

```
Static Semantics: VarScopedDeclarations
 FunctionStatementList : [empty]
    1. Return a new empty List.

 FunctionStatementList : StatementList
    1. Return the TopLevelVarScopedDeclarations of StatementList.
```

```
Static Semantics: TopLevelVarScopedDeclarations

 StatementList : StatementList StatementListItem
    1. Let declarations1 be TopLevelVarScopedDeclarations of StatementList.
    2. Let declarations2 be TopLevelVarScopedDeclarations of StatementListItem.
    3. Return the list-concatenation of declarations1 and declarations2.

StatementListItem : Statement
    1. If Statement is Statement : LabelledStatement , return TopLevelVarScopedDeclarations of Statement.
    2. Return VarScopedDeclarations of Statement.

StatementListItem : Declaration
    1. If Declaration is Declaration : HoistableDeclaration , then
        a. Let declaration be DeclarationPart of HoistableDeclaration.
        b. Return « declaration ».
    2. Return a new empty List.
```

```
// implicit definition of chain productions
Static Semantics: VarScopedDeclarations

Statement : BlockStatement
    1. Return VarScopedDeclarations of BlockStatement.

BlockStatement : Block
    1. Return VarScopedDeclarations of Block.

Block : { StatementList }
    1. Return VarScopedDeclarations of StatementList.
```

About "implicit definition of chain productions," see: [What is the implicit definition of “chain productions”?](./introduction-to-ecma-262#addition-what-is-the-implicit-definition-of-chain-productions)

```
Static Semantics: VarScopedDeclarations

 StatementList : StatementList StatementListItem
    1. Let declarations1 be VarScopedDeclarations of StatementList.
    2. Let declarations2 be VarScopedDeclarations of StatementListItem.
    3. Return the list-concatenation of declarations1 and declarations2.

StatementListItem : Declaration
    1. Return a new empty List.

VariableDeclarationList : VariableDeclaration
    1. Return « VariableDeclaration ».
```

### How are `VarDeclaredNames` collected?

Same as `VarScopedDeclarations`.

### How are `LexicallyScopedDeclarations` collected from `functionObject.[[ECMAScriptCode]]`?

In short, it collects top-level ClassDeclarations (`class`) and LexicalDeclarations (`let` and `const`).

```
Static Semantics: LexicallyScopedDeclarations
 ScriptBody : StatementList
    1. Return TopLevelLexicallyScopedDeclarations of StatementList.
```

```
Static Semantics: TopLevelLexicallyScopedDeclarations
 StatementList : StatementList StatementListItem

    1. Let declarations1 be TopLevelLexicallyScopedDeclarations of StatementList.
    2. Let declarations2 be TopLevelLexicallyScopedDeclarations of StatementListItem.
    3. Return the list-concatenation of declarations1 and declarations2.

StatementListItem : Statement

    1. Return a new empty List.

StatementListItem : Declaration

    1. If Declaration is Declaration : HoistableDeclaration , then
        a. Return a new empty List.
    2. Return « Declaration ».
```

### How are `LexicallyDeclaredNames` collected?

Same as `LexicallyScopedDeclarations`.

## Block

### The information needed in [`BlockDeclarationInstantiation(StatementList, blockEnv)`](https://262.ecma-international.org/13.0/index.html#sec-blockdeclarationinstantiation)

- [LexicallyScopedDeclarations](https://262.ecma-international.org/13.0/index.html#sec-static-semantics-lexicallyscopeddeclarations) of StatementList

### How are [LexicallyScopedDeclarations](https://262.ecma-international.org/13.0/index.html#sec-static-semantics-lexicallyscopeddeclarations) collected from StatementList?

```
Static Semantics: LexicallyScopedDeclarations

StatementList : StatementList StatementListItem

    1. Let declarations1 be LexicallyScopedDeclarations of StatementList.
    2. Let declarations2 be LexicallyScopedDeclarations of StatementListItem.
    3. Return the list-concatenation of declarations1 and declarations2.

StatementListItem : Statement

    1. If Statement is Statement : LabelledStatement , return LexicallyScopedDeclarations of LabelledStatement.
    2. Return a new empty List.
```

Since the `LexicallyScopedDeclarations` return empty list for the most of the statements except declarations and labelled statements, it means that collect the declarations from the current level are collected, while the declarations in nested blocks or functions are not.
