Part I: Understanding var, let, const and scope Click here to view Part II: Understanding fat arrow functions Preface This article is designed as a “get started” read for beginner to intermediate developers who wish to gain a better understanding of variables. ES6 As part of my “Getting to Grips with ES6” series, I aim to create a reference containing straight forward explanations ordered in short sections to help us understand and apply these concepts directly to our current development processes. Written by . You can find me on , , , and . Andrew Hill LinkedIn Twitter Instagram GitHub The ‘var’ Statement While the statement is not new to ES6, I strongly recommend reading through this refresher to help us better understand the concepts that the and statements introduce. var const let At its core, the statement allows us to define, update and redefine variables. Variables declared with are considered var var function scoped. Define and Update We can define and update variables declared with without any errors. var var test = 100; console.log(test);// Output: 100 test = 200; console.log(test);// Output: 200 Redefine (Allowed) We can also define an entirely new variable with the same name to override our previous variable with no errors. var test = 100; console.log(test);// Output: 100 var test = 200; console.log(test);// Output: 200 Scope Variables defined using are scoped as follows: var if they are defined within a function making them accessible only inside the function in which they are defined. Function scoped if they are not defined within a function making them accessible everywhere. Globally scoped Consider the following example: function scopeTest() {var test = 100;console.log(test);} scopeTest();// Output: 100 The variable is considered a local variable, function scoped to the function. We are able to access the value stored in the variable as both the variable declaration and the exist within the same function. test scopeTest() test console.log() scopeTest() Using a modified version of this example allows us to illustrate how this variable is not accessible outside of the function it is scoped to: function scopeTest() {var test = 100;} scopeTest(); console.log(test);// Output: [Error] 'test' is not defined. We are also allowed to update a variable at a higher scope to gain access to the value outside of the function. For reasons beyond the of this article, this is often considered bad practice and should be avoided unless absolutely necessary. scope var test; function scopeTest() {test = 100;} scopeTest(); console.log(test);// Output: 100 The “bad” side to var So why bring in the new and statements in ES6? const let Because any variable defined outside of a function using _var_ is globally scoped. Global scoping is as it introduces: bad - when you or or team cannot keep track of variable names, variables unintentionally get redefined and thereby overwritten. Naming collisions - Especially on the web, every user inherently has access to the global scope. Access to this allows users to see and modify your variables. Weakened Security - Although arguably negligible, the engine will look for a variable at a higher scope if it cannot find it where it is being currently being called. If your variables are all globally scoped, the engine will consistently need to make its way to the global window object in order to find the value it is looking for. Poor performance JavaScript The ‘let’ Statement The statement allows us to define and update variables much in the same way the statement does, but it does not allow us to redefine variables that are already defined in the same scope. Variables defined with are also considered let var let block scoped. Define and Update We can define and update variables declared with without any errors. let let test = 100; console.log(test);// Output: 100 test = 200; console.log(test);// Output: 200 Redefine (not allowed) Attempting to define a new variable with the same name as our previously defined variable is prohibited and results in errors. let let test = 100; console.log(test);// Output: 100 let test = 200;// Output: [Error] Identifier 'test' has already been declared. console.log(test);// Output: 100 The ‘const’ Statement The statement allows us to define variables only. Unlike which was made to be updated, prohibits updating variables entirely. Furthermore, like , prohibits the redefining of variables that have already been defined in the same scope. Variables defined with are considered const let const let const const block scoped. Define (allowed) and Update (not allowed) We can define variables but are prohibited from updating the values assigned to the variable. Attempting to update a const variable will result in errors. const const test = 100; console.log(test);// Output: 100 test = 200;// Output: [Error] Assignment to constant variable. console.log(test);// Output: 100 Redefine (not allowed) Attempting to define a new variable with the same name as our previously defined variable is prohibited and results in errors. const const test = 100; console.log(test);// Output: 100 const test = 200;// Output: [Error] Identifier 'test' has already been declared. console.log(test);// Output: 100 Mutability There is a growing misconception that is entirely immutable meaning you can never update an objects properties once it is assigned to a variable. When it comes to objects and , you cannot redefine the variable, but you allowed to update the properties of the object. const const const const are In the below example, we attempt to assign a new object to the variable. As previously covered, this is not allowed and we encounter errors. test const test = {milliseconds: 1862,createdBy: 'Andrew Hill',} test = {milliseconds: 1862,createdBy: 'Jane Doe',} // Output: [Error] Assignment to constant variable. console.log(test);// Output: Object { milliseconds: 1862, createdBy: 'Andrew Hill' } However, in this example we are able to update the properties of the variable without any problems. test const test = {milliseconds: 1862,createdBy: 'Andrew Hill',} test.createdBy = 'Jane Doe'; console.log(test);// Output: Object { milliseconds: 1862, createdBy: 'Jane Doe' } If you are looking for immutable objects, take a look at the method which prevents new properties from being added, existing properties from being removed, and prevents existing properties, their enumerability, configurability, and writability, from being changed. “truly” [Object.freeze()](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) Scope: const and let Variables defined using and are considered block scoped, meaning they are available to you inside the code block in which they are defined. A JavaScript code block is anything that falls within curly braces . Objects and functions both contain blocks and it is perfectly valid to have a block exist on its own. const let {} Consider the following example. Note that we are using in the below example, but the same rules apply to the way is scoped: let const function scopeTest() {let test = 100;console.log(test);} scopeTest();// Output: 100 In this example, the variable is considered a local variable, scoped to the block created by the function. We are able to access the value stored in the variable as both the variable declaration and the exist within the same function block. test scopeTest() test console.log() scopeTest() Using a modified version of this example allows us to illustrate how this variable is not accessible outside of the function block it is scoped to. function scopeTest() {let test = 100;} scopeTest(); console.log(test);// Output: [Error] test is not defined. Multiple variables can be defined with the same name using and so long as they do not fall within the same block. Doing this will result in two entirely different variables existing with the same name at different scopes. const let let test = 100; console.log(test);// Output: 100 function scopeTest() {let test = 200; console.log(test);// Output: 200} console.log(test);// Output: 100 Final Thoughts So what should you use when? There are some differing opinions on this matter which you can dig into with a few quick Google searches. Ultimately, I choose to use them in the way : Mathias Bynens describes in his article Use for all variable declarations by default. const Use only if rebinding is needed. let should not be used in ES6 var Thanks for reading. If you liked this article please consider supporting future installations of this series by recommending it. 👏 Click here to view Part II: Understanding fat arrow functions