You Don't Know JS Yet: Scope & Closures

4.Around the Global Scope

Browser "Window"

With respect to treatment of the global scope, the most pure environment JS can be run in is as a standalone .js file loaded in a web page environment in a browser

Globals Shadowing Globals

An unusual consequence of the difference between a global variable and a global property of the same name is that, within just the global scope itself, a global object property can be shadowed by a global variable

DOM Globals

ES Modules (ESM)

all variables that exist in the global scope are available as lexical identifiers from inside the module's scope.

Node

Node treats every single .js file that it loads, including the main one you start the Node process with, as a module

Global This

Global this = window

5.The Secret Lifecycle of Variables

Hoisting: Declaration vs. Expression

Function hoisting only applies to formal function declarations, not to function expression assignments

Variable Hoisting

The const keyword requires a variable to be initialized, so omitting an assignment from the declaration results in a SyntaxError

JS engine hoists the variables declared using the let keyword, but it doesn't initialize them as the variables declared with the var keyword.

Loops

for... for..in and for..of loops: the declared variable is treated as inside the loop body, and thus is handled per iteration

1.What's the Scope?

Compiled vs. Interpreted

Code compilation is a set of steps that process the text of your code and turn it into a list of instructions the computer can understand.

Interpretation the source code is transformed line by line

Compiling Code

1.Tokenizing/Lexing: breaking up a string of characters into meaningful (to the language) chunks, called tokens.

2.Parsing: taking a stream (array) of tokens and turning it into a tree of nested elements, which collectively represent the grammatical structure of the program

3.Code Generation: taking an AST and turning it into executable code.

Required: Two Phases

Syntax Errors from the Start

Early Errors

Hoisting

Compiler Speak

Targets (assignment operation)

Sources

Cheating: Runtime Scope Modifications

The eval(..) function receives a string of code to compile and execute on the fly during the program runtime

The with keyword, which essentially dynamically turns an object into a local scope

Date

Event

Highlights

Highlights

Event

Highlights

Highlights

2.Illustrating Lexical Scope

When the code wants to access a variable – the inner Lexical Environment is searched first, then the outer one, then the more outer one and so on until the global one.

6.Limiting Scope Exposure

Invoking Function Expressions Immediately

defining a function expression that's then immediately invoked.

IIFE is useful when we want to create a scope to hide variables/functions

Scoping with Blocks

In general, any { .. } curly-brace pair which is a statement will act as a block

What's the Catch?

The try...catch construct allows to handle runtime errors. It literally allows to “try” running the code and “catch” errors that may occur in it.

3.The Scope Chain

Shadowing

If you need to maintain two or more variables of the same name, you must use separate (often nested) scopes

Global Unshadowing Trick

window.variableName

Function Name Scope

Function declaration immediately becomes a ready-to-use function

Function expressions is created when the execution reaches it and is usable only from that moment

Arrow functions don't bind their own scope, but inherit it from the parent one, which in this case is window or the global object.

7.Using Closures

Observational

Closure is a function instance remembering its outer variables even as that function is passed to and invoked in other scopes

Implementational

Closure is a function instance and its scope environment preserved in-place while any references to it are passed around and invoked from other scopes

The benefits

Closure can improve code readability, bounding scope-exposure by encapsulating variable(s) inside function instances, while still making sure the information in those variables is accessible for future use

Closure can improve efficiency by allowing a function instance to remember previously determined information instead of having to compute it each time.

8.The Module Pattern

Encapsulation

The goal of encapsulation is the bundling or co-location of information (data) and behavior (functions) that together serve a common purpose.

What Is a Module?

A module is a collection of related data and functions (often referred to as methods in this context), characterized by a division between hidden private details and public accessible details, usually called the "public API."

A module is also stateful: it maintains some information over time, along with functionality to access and update that information.

Node CommonJS Modules

CommonJS modules are file-based; one module per file.

Modern ES Modules (ESM)

ESM is file-based, and module instances are singletons, with everything private by default.