Sign In Start Free Trial
Account

Add to playlist

Create a Playlist

Modal Close icon
You need to login to use this feature.
  • Book Overview & Buying Learn ECMAScript
  • Table Of Contents Toc
  • Feedback & Rating feedback
Learn ECMAScript

Learn ECMAScript - Second Edition

By : MOHAN, Narayan Prusty
4 (1)
close
close
Learn ECMAScript

Learn ECMAScript

4 (1)
By: MOHAN, Narayan Prusty

Overview of this book

Learn ECMAScript explores implementation of the latest ECMAScript features to add to your developer toolbox, helping you to progress to an advanced level. Learn to add 1 to a variable andsafely access shared memory data within multiple threads to avoid race conditions. You’ll start the book by building on your existing knowledge of JavaScript, covering performing arithmetic operations, using arrow functions and dealing with closures. Next, you will grasp the most commonly used ECMAScript skills such as reflection, proxies, and classes. Furthermore, you’ll learn modularizing the JS code base, implementing JS on the web and how the modern HTML5 + JS APIs provide power to developers on the web. Finally, you will learn the deeper parts of the language, which include making JavaScript multithreaded with dedicated and shared web workers, memory management, shared memory, and atomics. It doesn’t end here; this book is 100% compatible with ES.Next. By the end of this book, you'll have fully mastered all the features of ECMAScript!
Table of Contents (14 chapters)
close
close

The let keyword

The let keyword is used to declare a block-scoped variable (more on this later), optionally initializing it to a value. Programmers who come from a different programming language background, but are new to JavaScript, often end up writing error-prone JavaScript programs, believing that the JavaScript variables created using the traditional var keyword are block-scoped. Almost every popular programming language has the same set of rules when it comes to the variable scopes, but JavaScript acts a bit differently due to a lack of block-scoped variables. Due to the fact that JavaScript variables are not block-scoped, there are chances of memory leaks and JavaScript programs are harder to read and debug.

Declaring function-scoped variables

The JavaScript variables that are declared using the var keyword are called function-scoped variables. Function-scoped variables are accessible globally to the script, that is, throughout the script, if declared outside a function. Similarly, if the function scoped variables are declared inside a function, then they become accessible throughout the function, but not outside the function. Let's take a look at an example:

 var a = 12; // accessible everywhere
function myFunction() {
console.log(a); // alerts 12
var b = 13;
if(true) {
var c = 14; // this is also accessible throughout the function!
alert(b); // alerts 13
}
alert(c); // alerts 14
}
myFunction();
alert(b); // alerts undefined

Clearly, variables initialized inside a function are restricted inside that function only. However, variables declared in a block scope (that is, inside curly braces { } that is not a function (that is, if statements)) can be used outside those blocks as well.

Declaring block-scoped variables

Variables that are declared using the let keyword are called block-scoped variables. Block-scoped variables behave the same way as function-scoped variables when declared outside a function, that is, they are accessible globally. But when block-scoped variables are declared inside a block, they are accessible inside the block that they are defined in (and also any sub-blocks) but not outside the block:

 let a = 12; // accessible everywhere
function myFunction() {
console.log(a); // alerts 12
let b = 13;
if(true) {
let c = 14; // this is NOT accessible throughout the function!
alert(b); // alerts 13
}
alert(c); // alerts undefined
}
myFunction();
alert(b); // alerts undefined

Study the code carefully. This is the same as the preceding example, but with  var replaced by let everywhere. Observe how C alerts undefined now (let makes it inaccessible outside if {}).

Re-declaring variables

When you declare a variable using the var keyword that is already declared using  the var keyword (in the same scope) then it's overwritten. Consider this example:

var a = 0;
var a = 1;
alert(a); // alerts 1
function myFunction() {
var b = 2;
var b = 3;
alert(b); // alerts 3
}
myFunction();

The result is as expected. But the variables created using the let keyword don't behave in the same way.

When you declare a variable using the let keyword that is already declared using the let keyword in the same scope, then it throws a SyntaxError exception. Consider this example:

let a = 0;
let a = 1; // SyntaxError
function myFunction() {
let b = 2;
let b = 3; // SyntaxError
if(true) {
let c = 4;
let c = 5; // SyntaxError
}
}
myFunction();

When you declare a variable with a name that's already accessible in a function (or inner function), or is a sub-block using var or the let keyword respectively, then it's a different variable. Here, is an example this shows the behavior:

 var a = 1;
let b = 2;
function myFunction() {
var a = 3; // different variable
let b = 4; // different variable
if(true) {
var a = 5; // overwritten
let b = 6; // different variable
console.log(a); // 5
console.log(b); // 6
}
console.log(a); // 5
console.log(b); // 4
}
myFunction();
console.log(a);
console.log(b);

Closures and let keyword

Congratulations on making it to here! Let's face it, JavaScript has got some weird (and some bad) sides. Closures are on the weird side of JavaScript. Let's see what the term closure actually means.

When you declare a local variable, that variable has a restricted scope, that is, it cannot be used outside that particular scope within which it is declared (depends on var and let). As discussed earlier, local variables are not available outside the block (as in the case of let) or function scope (as in the case of var or let).

Let's take a look at the following example to understand what the preceding paragraph states:

function() {
var a = 1;
console.log(a); // 1
}
console.log(a); // Error

When a function is fully executed, that is, has returned its value, its local variables are no longer required and cleaned from memory. However, a closure is a persistent local variable scope. 

Consider the following example:

function counter () {
var count = 0;
return function () {
count += 1;
return count;
}
}

Clearly, the returned function makes use of the local variable to the counter() function. What happens when you call counter?

let myCounter = counter(); // returns a function (with count = 1)
myCounter(); // now returns 2
myCounter(); // now returns 3

Look carefully, we are not executing counter() again and again. We stored the returned value of the counter in the myCounter variable and then kept calling the returned function.

The returned myCounter function will count up by one each time it's called. When you call myCounter(), you are executing a function that contains a reference to a variable (count), which exists in a parent function and technically should've been destroyed after its complete execution. However, JavaScript preserves used variables inside a returned function in a kind of different stack. This property is called a closure.

Closures have been around for a long time, so what's different? Using it with the let keyword. Have a look at this one:

for(var i=0;i<5;i++){
setTimeout(function() {
console.log(i);
}, 1000);
}

The output will be:

 5 5 5 5 5 

Why? Because till the time setTimeout fires, the loop has already ended and the i variable was already 5. But this does not happen with let:

for(let i=0;i<5;i++){
setTimeout(function() {
console.log(i);
}, 1000);
}

Output:

0 1 2 3 4

The fact that let binds variables to the block (thus, in this case, the for loop) means that it binds the variable to every iteration. So, when the loop is finished, you have five setTimeout functions (with i = 0, 1, 2, 3, 4) waiting to fire one after another.

let achieves this by creating a closure of its own in every iteration. This happens behind the scenes with let, so you do not need to code that aspect.

To fix this code without let, we'll need to create an Immediately Invoked Function Expression (IIFE), which looks something like this:

for(var i=0;i<5;i++){
(function(arg) {
setTimeout(function() {
console.log(arg);
}, 1000);
}(i));
}

This is more or less what let does behind the scenes. So what happened here?

We created an anonymous function that is immediately invoked at every loop cycle with the correct i value associated with it. Now, this function has the correct i value passed as arg in the function argument. Finally, we use console.log after a second to get the correct output as 0 1 2 3 4.

So you can observe, a simple let statement can simplify the code a lot in such cases.

Visually different images
CONTINUE READING
83
Tech Concepts
36
Programming languages
73
Tech Tools
Icon Unlimited access to the largest independent learning library in tech of over 8,000 expert-authored tech books and videos.
Icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Icon 50+ new titles added per month and exclusive early access to books as they are being written.
Learn ECMAScript
notes
bookmark Notes and Bookmarks search Search in title playlist Add to playlist font-size Font size

Change the font size

margin-width Margin width

Change margin width

day-mode Day/Sepia/Night Modes

Change background colour

Close icon Search
Country selected

Close icon Your notes and bookmarks

Confirmation

Modal Close icon
claim successful

Buy this book with your credits?

Modal Close icon
Are you sure you want to buy this book with one of your credits?
Close
YES, BUY

Submit Your Feedback

Modal Close icon
Modal Close icon
Modal Close icon