Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can the "let" keyword be used in JavaScript to avoid global-scoped variables?

I was doing a test in JavaScript and I noticed that using the let keyword like

let variable = "I am a variable";
console.log(window.variable);

did not add a variable property to the window object. Does this mean that it does not exist in the global scope?

Could I declare variables without having to scope them inside a function or an IIFE?

I did search for this but could not find anything. Everyone says to use functions like {}() or simply access a unique global variable that contains the code, but seeing this made me wonder if it could be used for the purpose of avoiding these things.

like image 891
Lorthas Avatar asked Mar 31 '16 21:03

Lorthas


People also ask

Can we use let in global scope?

Description. let allows you to declare variables that are limited to the scope of a block statement, or expression on which it is used, unlike the var keyword, which declares a variable globally, or locally to an entire function regardless of block scope.

Is let function scoped?

let is block-scoped Hence when you try to access b outside of if block, an error occurs (as shown above in the program). Note: The variables declared inside a function will be function scoped for both var and let .

Is let function scope in JavaScript?

The let keyword is used to declare variables in JavaScript. The var keyword can also be used to declare variables, but the key difference between them lies in their scopes. var is function scoped while let is block scoped - we will discuss this in more detail later.

Is let global JavaScript?

Introduction to the JavaScript let keyword If you declare a variable outside of a function, the scope of the variable is global. When you declare a variable inside a function, the scope of the variable is local.


1 Answers

The let statement cannot be used to avoid global variables in the way that you suggest. A top-level let statement will still create variables in the global scope, it just won't create them as properties of the "global object" (typically window).

<script>
  'use strict';
  let fromLet = 'from let';
  var fromVar = 'from var';
</script>

<script>
  console.log(fromLet);        // 'from let'
  console.log(fromVar);        // 'from var'
  console.log(window.fromLet); // undefined
  console.log(window.fromVar); // 'from var'
</script>

This behaviour is primarily described in Section 8.1.1.4: Global Environment Records of the ECMAScript 6 specification. The gist of it is that there is a single global scope/namespace, but its values can be recorded in two different places. Global built-ins, function declarations, var declarations, and function* (generator) declarations are recorded as properties of the global object, while everything else global (from let, const, class, and other new constructs) is stored in an internal "environment record" which is not exposed as an object in the runtime.

Here are a few relevant excerpts to start from if you'd like to dig in to the details.

A global Environment Record is used to represent the outer most scope that is shared by all of the ECMAScript Script elements that are processed in a common Realm (8.2). A global Environment Record provides the bindings for built-in globals (clause 18), properties of the global object, and for all top-level declarations (13.2.8, 13.2.10) that occur within a Script.

Properties may be created directly on a global object. Hence, the object Environment Record component of a global Environment Record may contain both bindings created explicitly by FunctionDeclaration, GeneratorDeclaration, or VariableDeclaration declarations and binding created implicitly as properties of the global object. In order to identify which bindings were explicitly created using declarations, a global Environment Record maintains a list of the names bound using its CreateGlobalVarBindings and CreateGlobalFunctionBindings concrete methods.

Table 18 — Additional Fields of Global Environment Records

[[ObjectRecord]]: Object Environment Record

Binding object is the global object. It contains global built-in bindings as well as FunctionDeclaration, GeneratorDeclaration, and VariableDeclaration bindings in global code for the associated Realm.

[[DeclarativeRecord]]: Declarative Environment Record

Contains bindings for all declarations in global code for the associated Realm code except for FunctionDeclaration, GeneratorDeclaration, and VariableDeclaration bindings.

[[VarNames]]: List of String

The string names bound by FunctionDeclaration, GeneratorDeclaration, and VariableDeclaration declarations in global code for the associated Realm.

like image 170
Jeremy Avatar answered Sep 30 '22 23:09

Jeremy