In this series, I'll be sharing with you information and insights on what is one of the most popular programming languages in the world: JavaScript. Once upon a time, JavaScript was a simple client-side scripting language for the browser. Today, JavaScript exists on the server as well as the client and can be used to customize PDF files. Like any other programming language, JavaScript has its quirks and isn't perfect.

Related CODE Articles

For example, working with floating point numbers may be at odds with your need for precise numerical accuracy. No matter your vocation, to be effective, you need multiple tools in your toolbox, and that means, in a world of nails, JavaScript shouldn't be your only hammer.

Controlling variables and their scope is necessary for robust and maintainable JavaScript code.

The column's structure will be concise, like my Simplest Thing Possible series. Each column will be divided into four parts: context, core concepts, application, and key takeaways.

  • Before I can delve into the details, context is necessary. In the context, I'll set forth the issue or problem to be tackled.
  • The core concepts begin the journey into the details of how to solve the issue or problem set forth in the context. The core concepts consist of the specific language features covered in each column.
  • In the application section, I'll join theory to practice so that you can apply the material covered in the column.
  • In the key takeaways, I offer guidance and highlight the points you should consider when applying the column's material.

Let's get started!

Context

The context for the first JavaScript Corner column is to tackle the issue of JavaScript variables and scope. Prior to ECMAScript 6/2015, you either declared variables explicitly with the var statement or implicitly by assigning a value to a previously unused variable name. Depending on the circumstances, the variable was either local or global in scope. If the variable was declared outside of a function, the variable was global in scope regardless of whether the var statement was used, meaning that it was available to and could be changed by any other code in your application. On the other hand, if a variable is declared in a function using the var statement, the variable has local scope limited to that function as well as any blocks within that function. If the var statement isn't used, regardless of the fact that the variable is declared inside a function, that variable has global scope.

In JavaScript, a block is what exists between curly braces ({}).

Today, there are two additional statements, const and let, which help us control variables and their scope. Controlling variables and scope is necessary for robust and maintainable JavaScript code. As before, global and local scope is supported. In addition, block scoping is also supported. In the next section, I discuss the specific language features affected.

Core Concepts

The three language elements covered in this column include var, const, and let.

  • var: The var statement declares a variable and optionally, you can assign a value at the same time. For example, the following are valid ways to declare global variables in JavaScript:
var x;
var y = 1;
z = 1;
var a,b,c = 1;
  • To make the statements for variables x, y, a, b, and c local, you just need to wrap them in a function as follows:
function declare() {
    var x; //local
    var y = 1; //local
    var a,b,c = 1; //local
    z = 1; //global
}

Note that the z variable will still be global because the var statement is omitted.

  • const: New as of ECMAScript 6/2015, the const statement declares a block scope constant variable. The variable is constant to the extent that the variable cannot be re-declared nor can its value change within the same scope. If the variable is an object, property values can change.
  • let: New as of ECMAScript 6/2015, the let statement declares a block scope variable where its value can change but can only be declared once in a block. That block scope may be global or local depending on where the variable is declared. If declared outside a function, that particular instance will have global scope. If declared in a function or a block within a function, it will have function or block scope respectively. What if the variable is declared once at the function level and then again at a lower block level? Unlike previous JavaScript versions, while the lower block is executing, the new variable value controls. Upon exiting that block, the old value again controls.

Application

The applications that follow are used for illustration purposes only to show how these features work. They should not be taken as recommended approaches.

var

The following is a short review of the var statement's function level scope and the lack of block level scoping:

var x = 1;
(function() {
    var x = 2;
    console.log(x);
    //Output 2
    {
        var x = 3
        console.log(x);
        //Output 3
    }
    console.log(x);
    //Output 3 because var is only function
    //scope not block scoped
})();

console.log(x);
//Output 1

const

The following demonstrates that once a const has been declared and assigned (and the two must occur together), its value cannot change:

const x = 1;
x = 2;
//Results in a Assignment to constant
//variable error

The prohibition on value changes doesn't extend to object properties. The following is permissible:

const x = {"Name" : "x"};
console.log(x.Name);
//Output x
x.Name = 'X';
console.log(x.Name);
//Output X

The following illustrates that it's impermissible to redeclare a const at the same block level:

const x = 2;
const x = 1;
//Results in an Identifier  'x' has already been declared error

If different blocks are involved, because const has block scope, earlier variable declarations are available to later blocks. If the same variable name is used in a later block, the earlier declaration value is preserved and reinstated after the later block executes:

const x = 1;
(function() {
    const x = 2;
    console.log(x);
    //Output 2
    {
        const x = 3;
        console.log(x)
        //Output 3
    }
})();
console.log(x);
//Output 1

let

The best way to think of the let statement is that it's like const plus the ability to re-assign values. Assuming that you can rely on full ECMAScript 6/2015 support, if you need to re-assign values, use let. If you don't need to re-assign values or the value is an object, use const.

Key Takeaways

The var, const, and let statements are only alike in that they are ways of declaring JavaScript variables.

  • The var statement is only global and local/function scoped.
  • The const and let statements go a step further to supporting block scoping. A const variable within the same scope can only be declared once and its value cannot change. If the value is an object, individual properties can change at any time.
  • The let statement is like const with respect to scoping and, like const, a let variable cannot be redeclared within the same scope. You can reassign values using let.

How const and let function is straightforward both as to how they are different from each other, how they differ from the var statement and how their scope can be managed. The main question you may have right now is whether you should stop using the var statement in favor of the let and const statements.

For existing code, assuming you have used good practices like the module-pattern, there's no reason to ever change that code. For new code, in my opinion, it's too early to discard var entirely. If you do choose to go that route, be sure to thoroughly test your code against the browsers you support.

Alternatively, consider using a transpiler like Traceur that allows you to write tomorrow's JavaScript and take advantage of those features today and have it automatically converted to today's JavaScript that you know will work across most/all browsers. Transpilers are a great way to manage present development with the latest language version in the context varying support for new language features. A good resource to determine browser support is here: http://kangax.github.io/compat-table/es6/.