• Home
  • ES6
  • ADVANCED
    • Javascript Array Methods
    • Javascript String Methods
    • Javascript Regex
    • ES Next
  • JS BOM
  • JS DOM
  • WEB API
  • SNIPPETS
  • TYPESCRIPT
  • Golang
  • Dark Mode Light Mode
  • » es6 » javaScript-let
    <h1 id="javascript-let-declaring-block-scoped-variables">JavaScript let: Declaring Block-Scoped Variables</h1> <p><strong>Summary</strong>: in this tutorial, you will learn how to use the JavaScript <code>let</code> keyword to declare block-scoped variables.</p> <h2 id="introduction-to-the-javascript-let-keyword">Introduction to the JavaScript let keyword</h2> <p>In ES5, when you <a href="https://www.javascripttutorial.net/javascript-variables/">declare a variable</a> using the <code>var</code> keyword, the scope of the variable is either global or local. 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.</p> <p>ES6 provides a new way of declaring a variable by using the <code>let</code> keyword. The <code>let</code> keyword is similar to the <code>var</code> keyword, except that these variables are blocked-scope. For example:</p> <pre><code class="hljs language-js"><span class="hljs-keyword">let</span> variable_name;<span class="hljs-title class_">Code</span> <span class="hljs-attr">language</span>: <span class="hljs-title class_">JavaScript</span> (javascript) </code></pre> <p>In JavaScript, blocks are denoted by curly braces <code>{}</code> , for example, the <code>if else</code>, <code>for</code>, <code>do while</code>, <code>while</code>, <code>try catch</code> and so on:</p> <pre><code class="hljs language-js"><span class="hljs-keyword">if</span>(condition) { <span class="hljs-comment">// inside a block</span> }<span class="hljs-title class_">Code</span> <span class="hljs-attr">language</span>: <span class="hljs-title class_">JavaScript</span> (javascript) </code></pre> <p>See the following example:</p> <pre><code class="hljs language-js"><span class="hljs-keyword">let</span> x = <span class="hljs-number">10</span>; <span class="hljs-keyword">if</span> (x == <span class="hljs-number">10</span>) { <span class="hljs-keyword">let</span> x = <span class="hljs-number">20</span>; <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(x); <span class="hljs-comment">// 20: reference x inside the block</span> } <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(x); <span class="hljs-comment">// 10: reference at the begining of the scriptCode language: JavaScript (javascript)</span> </code></pre> <p>How the script works:</p> <ul> <li>First, declare a variable <code>x</code> and initialize its value to 10.</li> <li>Second, declare a new variable with the same name <code>x</code> inside the <code>if</code> block but with an initial value of 20.</li> <li>Third, output the value of the variable <code>x</code> inside and after the <a href="https://www.javascripttutorial.net/javascript-if-else/"><code>if</code></a> block.</li> </ul> <p>Because the <code>let</code> keyword declares a block-scoped variable, the <code>x</code> variable inside the <code>if</code> block is a <strong>new variable</strong> and it shadows the <code>x</code> variable declared at the top of the script. Therefore, the value of <code>x</code> in the console is <code>20</code>.</p> <p>When the JavaScript engine completes executing the <code>if</code> block, the <code>x</code> variable inside the <code>if</code> block is out of scope. Therefore, the value of the <code>x</code> variable that following the <code>if </code>block is 10.</p> <h2 id="javascript-let-and-global-object">JavaScript let and global object</h2> <p>When you declare a global variable using the <code>var</code> keyword, you add that variable to the property list of the <a href="https://www.javascripttutorial.net/es-next/javascript-globalthis/">global object</a>. In the case of the web browser, the global object is the <code>window</code>. For example:</p> <pre><code class="hljs language-js"><span class="hljs-keyword">var</span> a = <span class="hljs-number">10</span>; <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">window</span>.<span class="hljs-property">a</span>); <span class="hljs-comment">// 10Code language: JavaScript (javascript)</span> </code></pre> <p>However, when you use the <code>let</code> keyword to declare a variable, that variable is <strong>not</strong> attached to the global object as a property. For example:</p> <pre><code class="hljs language-js"><span class="hljs-keyword">let</span> b = <span class="hljs-number">20</span>; <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">window</span>.<span class="hljs-property">b</span>); <span class="hljs-comment">// undefinedCode language: JavaScript (javascript)</span> </code></pre> <h2 id="javascript-let-and-callback-function-in-a-for-loop">JavaScript let and callback function in a for loop</h2> <p>See the following example.</p> <pre><code class="hljs language-js"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">5</span>; i++) { <span class="hljs-built_in">setTimeout</span>(<span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(i); }, <span class="hljs-number">1000</span>); }<span class="hljs-title class_">Code</span> <span class="hljs-attr">language</span>: <span class="hljs-title class_">JavaScript</span> (javascript) </code></pre> <p>The intention of the code is to output numbers from 0 to 4 to the console every second. However, it outputs the number <code>5</code> five times:</p> <pre><code class="hljs language-js"><span class="hljs-number">5</span> <span class="hljs-number">5</span> <span class="hljs-number">5</span> <span class="hljs-number">5</span> <span class="hljs-number">5</span> </code></pre> <p>In this example, the variable <code>i</code> is a global variable. After the loop, its value is 5. When the callback functions are passed to the <code>setTimeout()</code> function executes, they reference the same variable <code>i</code> with the value 5.</p> <p>In ES5, you can fix this issue by creating another scope so that each callback function references a new variable. And to create a new scope, you need to create a function. Typically, you use the <a href="https://www.javascripttutorial.net/javascript-immediately-invoked-function-expression-iife/">IIFE</a> pattern as follows:</p> <pre><code class="hljs language-js"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">5</span>; i++) { (<span class="hljs-keyword">function</span> (<span class="hljs-params">j</span>) { <span class="hljs-built_in">setTimeout</span>(<span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(j); }, <span class="hljs-number">1000</span>); })(i); }<span class="hljs-title class_">Code</span> <span class="hljs-attr">language</span>: <span class="hljs-title class_">JavaScript</span> (javascript) </code></pre> <p>Output:</p> <pre><code class="hljs language-js"><span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> </code></pre> <p>In ES6, the <code>let</code> keyword declares a new variable in each loop iteration. Therefore, you just need to replace the <code>var</code> keyword with the <code>let</code> keyword to fix the issue:</p> <pre><code class="hljs language-js"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">5</span>; i++) { <span class="hljs-built_in">setTimeout</span>(<span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(i); }, <span class="hljs-number">1000</span>); }<span class="hljs-title class_">Code</span> <span class="hljs-attr">language</span>: <span class="hljs-title class_">JavaScript</span> (javascript) </code></pre> <p>To make the code completely ES6 style, you can use an <a href="https://www.javascripttutorial.net/es6/javascript-arrow-function/">arrow function</a> as follows:</p> <pre><code class="hljs language-js"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">5</span>; i++) { <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(i), <span class="hljs-number">1000</span>); }<span class="hljs-title class_">Code</span> <span class="hljs-attr">language</span>: <span class="hljs-title class_">JavaScript</span> (javascript) </code></pre> <p>Note that you’ll learn more about the <a href="https://www.javascripttutorial.net/es6/javascript-arrow-function/">arrow functions in the later tutorial</a>.</p> <h2 id="redeclaration">Redeclaration</h2> <p>The <code>var</code> keyword allows you to redeclare a variable without any issue:</p> <pre><code class="hljs language-js"><span class="hljs-keyword">var</span> counter = <span class="hljs-number">0</span>; <span class="hljs-keyword">var</span> counter; <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(counter); <span class="hljs-comment">// 0Code language: JavaScript (javascript)</span> </code></pre> <p>However, redeclaring a variable using the <code>let</code> keyword will result in an error:</p> <pre><code class="hljs language-js"><span class="hljs-keyword">let</span> counter = <span class="hljs-number">0</span>; <span class="hljs-keyword">let</span> counter; <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(counter);<span class="hljs-title class_">Code</span> <span class="hljs-attr">language</span>: <span class="hljs-title class_">JavaScript</span> (javascript) </code></pre> <p>Here’s the error message:</p> <pre><code class="hljs language-js"><span class="hljs-title class_">Uncaught</span> <span class="hljs-title class_">SyntaxError</span>: <span class="hljs-title class_">Identifier</span> <span class="hljs-string">&#x27;counter&#x27;</span> has already been declaredCode <span class="hljs-attr">language</span>: <span class="hljs-title class_">JavaScript</span> (javascript) </code></pre> <h2 id="javascript-let-variables-and-hoisting">JavaScript let variables and hoisting</h2> <p>Let’s examine the following example:</p> <pre><code class="hljs language-js">{ <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(counter); <span class="hljs-comment">// </span> <span class="hljs-keyword">let</span> counter = <span class="hljs-number">10</span>; }<span class="hljs-title class_">Code</span> <span class="hljs-attr">language</span>: <span class="hljs-title class_">JavaScript</span> (javascript) </code></pre> <p>This code causes an error:</p> <pre><code class="hljs language-js"><span class="hljs-title class_">Uncaught</span> <span class="hljs-title class_">ReferenceError</span>: <span class="hljs-title class_">Cannot</span> access <span class="hljs-string">&#x27;counter&#x27;</span> before initializationCode <span class="hljs-attr">language</span>: <span class="hljs-title class_">JavaScript</span> (javascript) </code></pre> <p>In this example, accessing the <code>counter</code> variable before declaring it causes a <code>ReferenceError</code>. You may think that a variable declaration using the <code>let</code> keyword does not <strong>hoist,</strong> but it does**.**</p> <p>In fact, the JavaScript engine will hoist a variable declared by the <code>let</code> keyword to the top of the block. However, the JavaScript engine does not initialize the variable. Therefore, when you reference an uninitialized variable, you’ll get a <code>ReferenceError</code>.</p> <h2 id="temporal-death-zone-tdz">Temporal death zone (TDZ)</h2> <p>A variable declared by the <code>let</code> keyword has a so-called temporal dead zone (TDZ). The TDZ is the time from the start of the block until the variable declaration is processed.</p> <p>The following example illustrates that the temporal dead zone is time-based, not location-based*.*</p> <pre><code class="hljs language-js">{ <span class="hljs-comment">// enter new scope, TDZ starts</span> <span class="hljs-keyword">let</span> log = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(message); <span class="hljs-comment">// messagedeclared later</span> }; <span class="hljs-comment">// This is the TDZ and accessing log</span> <span class="hljs-comment">// would cause a ReferenceError</span> <span class="hljs-keyword">let</span> message= <span class="hljs-string">&#x27;Hello&#x27;</span>; <span class="hljs-comment">// TDZ ends</span> <span class="hljs-title function_">log</span>(); <span class="hljs-comment">// called outside TDZ</span> }<span class="hljs-title class_">Code</span> <span class="hljs-attr">language</span>: <span class="hljs-title class_">JavaScript</span> (javascript) </code></pre> <p>In this example:</p> <p>First, the curly brace starts a new block scope, therefore, the TDZ starts.</p> <p>Second, the <code>log()</code> function expression accesses the <code>message</code> variable. However, the <code>log()</code> function has not been executed yet.</p> <p>Third, declare the <code>message</code> variable and initialize its value to 10. The time from the start of the block scope to the time that the <code>message</code> variable is accessed is called a <em>temporal death zone</em>. When the JavaScript engine processes the declaration, the TDZ ends.</p> <p>Finally, call the <code>log()</code> function that accesses the <code>message</code> variable outside of the TDZ.</p> <p>Note that if you access a variable declared by the <code>let</code> keyword in the TDZ, you’ll get a <code>ReferenceError</code> as illustrated in the following example.</p> <pre><code class="hljs language-js">{ <span class="hljs-comment">// TDZ starts</span> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-keyword">typeof</span> myVar); <span class="hljs-comment">// undefined</span> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-keyword">typeof</span> message); <span class="hljs-comment">// ReferenceError</span> <span class="hljs-keyword">let</span> message; <span class="hljs-comment">// TDZ ends</span> }<span class="hljs-title class_">Code</span> <span class="hljs-attr">language</span>: <span class="hljs-title class_">JavaScript</span> (javascript) </code></pre> <p>Notice that <code>myVar</code> variable is a non-existing variable, therefore, its type is <a href="https://www.javascripttutorial.net/javascript-data-types/#undefined">undefined</a>.</p> <p>The temporal death zone prevents you from accidentally referencing a variable before its declaration.</p> <h3 id="summary">Summary</h3> <ul> <li>Variables are declared using the <code>let</code> keyword are block-scoped, are not initialized to any value, and are not attached to the global object.</li> <li>Redeclaring a variable using the <code>let</code> keyword will cause an error.</li> <li>A temporal dead zone of a variable declared using the <code>let</code> keyword starts from the block until the initialization is evaluated.</li> </ul>

    ES6 Tutorial

    NEW ES6 SYNTAX

  • JavaScript let
  • var vs. let
  • JavaScript const
  • Template Literals
  • Object Literal Syntax Extensions
  • Default Parameters
  • Rest Parameters
  • Spread Operator
  • Destructuring
  • for…of Loop
  • Octal and Binary Literals
  • ES6 MODULE & CLASS

  • Class
  • Getters & Setters
  • Class Expressions
  • Computed Properties
  • Inheritance
  • new.target
  • About Me

    • Made by Rasel Mahmud
    • Portfolio

    Top References

    • javascripttutorial.net
    • W3school.com

    Top Tutorials

    • Primitive vs. Reference Values
    • What is JavaScript

    NOTE:

    This website only for Developing purpose not for business. and all content copied from other place like javascripttutorial.net and W3school.com