[javascript] What is the scope of variables in JavaScript?

Old school JavaScript

Traditionally, JavaScript really only has two types of scope :

  1. Global Scope : Variables are known throughout the application, from the start of the application (*)
  2. Functional Scope : Variables are known within the function they are declared in, from the start of the function (*)

I will not elaborate on this, since there are already many other answers explaining the difference.


Modern JavaScript

The most recent JavaScript specs now also allow a third scope :

  1. Block Scope : Identifiers are "known" from the top of the scope they are declared within, but they cannot be assigned to or dereferenced (read) until after the line of their declaration. This interim period is called the "temporal dead zone."

How do I create block scope variables?

Traditionally, you create your variables like this :

var myVariable = "Some text";

Block scope variables are created like this :

let myVariable = "Some text";

So what is the difference between functional scope and block scope?

To understand the difference between functional scope and block scope, consider the following code :

// i IS NOT known here
// j IS NOT known here
// k IS known here, but undefined
// l IS NOT known here

function loop(arr) {
    // i IS known here, but undefined
    // j IS NOT known here
    // k IS known here, but has a value only the second time loop is called
    // l IS NOT known here

    for( var i = 0; i < arr.length; i++ ) {
        // i IS known here, and has a value
        // j IS NOT known here
        // k IS known here, but has a value only the second time loop is called
        // l IS NOT known here
    };

    // i IS known here, and has a value
    // j IS NOT known here
    // k IS known here, but has a value only the second time loop is called
    // l IS NOT known here

    for( let j = 0; j < arr.length; j++ ) {
        // i IS known here, and has a value
        // j IS known here, and has a value
        // k IS known here, but has a value only the second time loop is called
        // l IS NOT known here
    };

    // i IS known here, and has a value
    // j IS NOT known here
    // k IS known here, but has a value only the second time loop is called
    // l IS NOT known here
}

loop([1,2,3,4]);

for( var k = 0; k < arr.length; k++ ) {
    // i IS NOT known here
    // j IS NOT known here
    // k IS known here, and has a value
    // l IS NOT known here
};

for( let l = 0; l < arr.length; l++ ) {
    // i IS NOT known here
    // j IS NOT known here
    // k IS known here, and has a value
    // l IS known here, and has a value
};

loop([1,2,3,4]);

// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here

Here, we can see that our variable j is only known in the first for loop, but not before and after. Yet, our variable i is known in the entire function.

Also, consider that block scoped variables are not known before they are declared because they are not hoisted. You're also not allowed to redeclare the same block scoped variable within the same block. This makes block scoped variables less error prone than globally or functionally scoped variables, which are hoisted and which do not produce any errors in case of multiple declarations.


Is it safe to use block scope variables today?

Whether or not it is safe to use today, depends on your environment :

  • If you're writing server-side JavaScript code (Node.js), you can safely use the let statement.

  • If you're writing client-side JavaScript code and use a browser based transpiler (like Traceur or babel-standalone), you can safely use the let statement, however your code is likely to be anything but optimal with respect to performance.

  • If you're writing client-side JavaScript code and use a Node based transpiler (like the traceur shell script or Babel), you can safely use the let statement. And because your browser will only know about the transpiled code, performance drawbacks should be limited.

  • If you're writing client-side JavaScript code and don't use a transpiler, you need to consider browser support.

    These are some browsers that don't support let at all :

    • Internet explorer 10 and below
    • Firefox 43 and below
    • Safari 9 and below
    • Android browser 4 and below
    • Opera 27 and below
    • Chome 40 and below
    • ANY version of Opera Mini & Blackberry Browser

enter image description here


How to keep track of browser support

For an up-to-date overview of which browsers support the let statement at the time of your reading this answer, see this Can I Use page.


(*) Globally and functionally scoped variables can be initialized and used before they are declared because JavaScript variables are hoisted. This means that declarations are always much to the top of the scope.

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to function

$http.get(...).success is not a function Function to calculate R2 (R-squared) in R How to Call a Function inside a Render in React/Jsx How does Python return multiple values from a function? Default optional parameter in Swift function How to have multiple conditions for one if statement in python Uncaught TypeError: .indexOf is not a function Proper use of const for defining functions in JavaScript Run php function on button click includes() not working in all browsers

Examples related to variables

When to create variables (memory management) How to print a Groovy variable in Jenkins? What does ${} (dollar sign and curly braces) mean in a string in Javascript? How to access global variables How to initialize a variable of date type in java? How to define a variable in a Dockerfile? Why does foo = filter(...) return a <filter object>, not a list? How can I pass variable to ansible playbook in the command line? How do I use this JavaScript variable in HTML? Static vs class functions/variables in Swift classes?

Examples related to scope

Angular 2 - Using 'this' inside setTimeout Why Is `Export Default Const` invalid? How do I access previous promise results in a .then() chain? Problems with local variable scope. How to solve it? Why is it OK to return a 'vector' from a function? Uncaught TypeError: Cannot read property 'length' of undefined Setting dynamic scope variables in AngularJs - scope.<some_string> How to remove elements/nodes from angular.js array Limiting number of displayed results when using ngRepeat A variable modified inside a while loop is not remembered

Examples related to var

how to display a javascript var in html body ReferenceError: variable is not defined Initialize value of 'var' in C# to null What is /var/www/html? How can I write these variables into one line of code in C#? Why should I use var instead of a type? What is the equivalent of the C# 'var' keyword in Java? PHPDoc type hinting for array of objects? What's the difference between using "let" and "var"? What is the scope of variables in JavaScript?