JavaScript Variable Scope and Hoisting Explained

»jan. 31 Last Year 68

In this post, we will learn JavaScript’s variable scope and hoisting and all the idiosyncrasies of both.

We must understand how variable scope and variable hoisting work in JavaScript, if want to understand JavaScript well. These concepts may seem straightforward; they are not. Some important subtleties exist that we must understand, if we want to thrive and excel as JavaScript developers.

  • Receive Updates

Variable Scope
A variable’s scope is the context in which the variable exists. The scope specifies from where you can access a variable and whether you have access to the variable in that context.

Variables have either a local scope or a global scope.

Local Variables (Function-level scope)
Unlike most programming languages, JavaScript does not have block-level scope (variables scoped to surrounding curly brackets); instead, JavaScript has function-level scope. Variables declared within a function are local variables and are only accessible within that function or by functions inside that function. See my post on Closures for more on accessing variables in outer functions from inner functions.

Demonstration of Function-Level Scope

var name = "Richard";

function showName () {
	var name = "Jack"; // local variable; only accessible in this showName function
	console.log (name); // Jack
}
console.log (name); // Richard: the global variable

No Block-Level Scope

var name = "Richard";
// the blocks in this if statement do not create a local context for the name variable
if (name) {
	name = "Jack"; // this name is the global name variable and it is being changed to "Jack" here
	console.log (name); // Jack: still the global variable
}

// Here, the name variable is the same global name variable, but it was changed in the if statement
console.log (name); // Jack
  • If You Don’t Declare Your Local Variables, Trouble is Nigh
    Always declare your local variables before you use them. In fact, you should use JSHint to check your code for syntax errors and style guides. Here is the trouble with not declaring local variables:
    


    // If you don't declare your local variables with the var keyword, they are part of the global scope
    var name = "Michael Jackson";
    
    function showCelebrityName () {
    	console.log (name);
    }
    
    function showOrdinaryPersonName () {	
    	name = "Johnny Evers";
    	console.log (name);
    }
    showCelebrityName (); // Michael Jackson
    
    // name is not a local variable, it simply changes the global name variable
    showOrdinaryPersonName (); // Johnny Evers
    
    // The global variable is now Johnny Evers, not the celebrity name anymore
    showCelebrityName (); // Johnny Evers
    
    // The solution is to declare your local variable with the var keyword
    function showOrdinaryPersonName () {	
    	var name = "Johnny Evers"; // Now name is always a local variable and it will not overwrite the global variable
    	console.log (name);
    }
  • Local Variables Have Priority Over Global Variables in Functions
    If you declare a global variable and a local variable with the same name, the local variable will have priority when you attempt to use the variable inside a function (local scope):

    var name = "Paul";
    
    function users () {
    	// Here, the name variable is local and it takes precedence over the same name variable in the global scope
    var name = "Jack";
    
    // The search for name starts right here inside the function before it attempts to look outside the function in the global scope
    console.log (name); 
    }
    
    users (); // Jack

Global Variables
All variables declared outside a function are in the global scope. In the browser, which is what we are concerned with as front-end developers, the global context or scope is the window object (or the entire HTML document).

  • Any variable declared or initialized outside a function is a global variable, and it is therefore available to the entire application. For example:
    // To declare a global variable, you could do any of the following:
    var myName = "Richard";
    
    // or even
    firstName = "Richard";
    
    // or 
    var name; //
    name;
    </pre>
    
    It is important to note that all global variables are attached to the window object. So, all the global variables we just declared can be accessed on the window object like this:
    
    console.log(window.myName); // Richard;
    
     // or
    console.log("myName" in window); // true
    console.log("firstName" in window); // true
    </pre>
    
  • If a variable is initialized (assigned a value) without first being declared with the var keyword, it is automatically added to the global context and it is thus a global variable:
    function showAge () {
    	// Age is a global variable because it was not declared with the var keyword inside this function
    	age = 90;
    	console.log(age);// 
    }
    
    showAge (); // 90
    
    // Age is in the global context, so it is available here, too
    console.log(age); // 90

    Demonstration of variables that are in the Global scope even as they seem otherwise:

    // Both firstName variables are in the global scope, even though the second one is surrounded by a block {}. 
    var firstName = "Richard";
    {
    var firstName = "Bob";
    }
    
    // To reiterate: JavaScript does not have block-level scope
    
    // The second declaration of firstName simply re-declares and overwrites the first one
    console.log (firstName); // Bob

    Another example

    for (var i = 1; i <= 10; i++) {
    	console.log (i); // outputs 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
    };
    
    // The variable i is a global variable and it is accessible in the following function with the last value it was assigned above 
    function aNumber () {
    console.log(i);
    }
    
    // The variable i in the aNumber function below is the global variable i that was changed in the for loop above. Its last value was 11, set just before the for loop exited:
    aNumber ();  // 11
    
  • setTimeout Variables are Executed in the Global Scope
    Note that all functions in setTimeout are executed in the global scope. This is a tricky bit; consider this:

     // The use of the "this" object inside the setTimeout function refers to the Window object, not to myObj
    
    var highValue = 200;
    var constantVal = 2;
    var myObj = {
    	highValue: 20,
    	constantVal: 5,
    	calculateIt: function () {
     setTimeout (function  () {
    	console.log(this.constantVal * this.highValue);
    }, 2000);
    	}
    }
    
    // The "this" object in the setTimeout function used the global highValue and constantVal variables, because the reference to "this" in the setTimeout function refers to the global window object, not to the myObj object as we might expect.
    
    myObj.calculateIt(); // 400
    // This is an important point to remember.
  • Do not Pollute the Global Scope
    If you want to become a JavaScript master, which you certainly want to do (otherwise you will be watching Honey Boo Boo right now), you have to know that it is important to avoid creating many variables in the global scope, such as this:

    // These two variables are in the global scope and they shouldn't be here
    var firstName, lastName;
    
    function fullName () {
    	console.log ("Full Name: " + firstName + " " + lastName );
    }

    This is the improved code and the proper way to avoid polluting the global scope

    // Declare the variables inside the function where they are local variables
    
    function fullName () {
    	var firstName = "Michael", lastName = "Jackson";
    
    	console.log ("Full Name: " + firstName + " " + lastName );
    }

    In this last example, the function fullName is also in the global scope.


Variable Hoisting
All variable declarations are hoisted (lifted and declared) to the top of the function, if defined in a function, or the top of the global context, if outside a function.

It is important to know that only variable declarations are hoisted to the top, not variable initialization or assignments (when the variable is assigned a value).

Variable Hoisting Example:

function showName () {
console.log ("First Name: " + name);
var name = "Ford";
console.log ("Last Name: " + name);
}

showName (); 
// First Name: undefined
// Last Name: Ford

// The reason undefined prints first is because the local variable name was hoisted to the top of the function
// Which means it is this local variable that get calls the first time.
// This is how the code is actually processed by the JavaScript engine:

function showName () {
	var name; // name is hoisted (note that is undefined at this point, since the assignment happens below)
console.log ("First Name: " + name); // First Name: undefined

name = "Ford"; // name is assigned a value

// now name is Ford
console.log ("Last Name: " + name); // Last Name: Ford
}

Function Declaration Overrides Variable Declaration When Hoisted
Both function declaration and variable declarations are hoisted to the top of the containing scope. And function declaration takes precedence over variable declarations (but not over variable assignment). As is noted above, variable assignment is not hoisted, and neither is function assignment. As a reminder, this is a function assignment: var myFunction = function () {}.
Here is a basic example to demonstrate:

 // Both the variable and the function are named myName
var myName;

function myName () {
console.log ("Rich");
}

// The function declaration overrides the variable name
console.log(typeof myName); // function
 // But in this example, the variable assignment overrides the function declaration
var myName = "Richard"; // This is the variable assignment (initialization) that overrides the function declaration.

function myName () {
console.log ("Rich");
}

console.log(typeof myName); // string 

It is important to note that function expressions, such as the example below, are not hoisted.

var myName = function () {
console.log ("Rich");
} 

In strict mode, an error will occur if you assign a variable a value without first declaring the variable. Always declare your variables.

Be good. Sleep well. And enjoy coding.

Six Courses Coming Soon (Updated)

Don't learn JavaScript, Meteor, Node, Backbone, or any other web-dev technologies until you see our course offering or at least until you use our Modern Developer Technology Guide to determine which specific set of technologies you need to learn and use to accomplish your goals. Both are coming soon.

Get a Complete Web-Dev Education

Each course is part of a Career Path, a complete web dev education. About 3 to 6 courses make up a Career Path. Note the following Career Paths you can choose from:

  • jQuery Developer/Designer, Junior Front-end Developer, Web Developer, or JavaScript Developer (2 courses)
  • The Modern Front-end Developer (3 courses)
  • Designer to Developer: Designer Building a Startup (3–4 courses)
  • The Front-end-Framework-Equipped Modern Front-end Developer (4 courses)
  • Full-stack Modern Developer (4–6 courses)
  • Startup-Bound Developer (Build complex database-driven startups like Facebook and Twitter) (4–6 courses)
  • HTML5/JavaScript Mobile Developer (Build mobile apps for Android and iOS using your JavaScript skills)
  • iOS Developer (Build native iPhone/iPad apps)

First Ever JavaScriptIsSexy.com Courses

In a few weeks, look out for six comprehensive courses, unlike any you can find elsewhere online. Our Career Paths provide the best value—more comprehensive (we teach you everything), more relevant (latest and most apt technologies), and more affordable (~90% less than programming boot camps; ~99% less than college) than other similar courses, online or offline. You will learn more about modern web development (in 4–6 months) in our Career Paths than you would at any 4-year university.
  1. Course 1: Essential JavaScript and Modern Web Application Development

    You can't develop modern applications with just JavaScript.

    What You Will Learn
    In this course, you will learn beginning to intermediate JavaScript along with all the relevant and necessary technologies and tools to develop complete modern web applications on the front end. Note that JavaScript by itself is just about 35% of what you have to learn to develop modern web applications, even simple web applications.

    Who Is this Course For?
    — Anyone with at least some high school education
    — No programming experience necessary

    You will be able to develop complete moderately complex front-end web applications using JavaScript and other tools and technologies.

  2. Course 2: Mastering JavaScript and Modern Web Application Development

    Become a proficient modern JavaScript developer.

    What You Will Learn
    In this course, you will learn intermediate to advanced JavaScript along with all the relevant and necessary (intermediate to advanced) technologies and tools to develop complex modern web applications, though not database-driven apps.

    Who Is this Course For?
    — Completed at least the "essential" course

    What will graduating from this course allow you to do?
    Work as a jQuery Developer/Designer, Junior Front-end Developer, Web Developer, or JavaScript Developer. JavaScript and Web Developers with similar expertise can easily make $70,000 a year. (Salary varies by city and developer's expertise and experience.)

  3. Course 3: The Modern Front-end Developer

    Become a qualified Front-end Developer and make a huge salary or develop your own startup—if you take the "Skip-the-backend" course.

    What You Will Learn
    In this course, you will learn everything (except a specific front-end framework; see the next course) you need to learn to become a highly qualified Front-end Developer. You will learn not just JavaScript, but all the latest technologies and tools that modern front-end developers must know.

    Who is this course for?
    — Completed course 1
    — And graduated from course 2

    What Will Graduating from This Course Allow You to Do?
    Front-end developers are in high demand, perhaps more so than any other programmers, and they make more than $80,000 a year. (Salary varies by city and developer's expertise and experience.)

    We will prepare you for jobs and connect you with agencies and employers, when you graduate from the "Front-end Career Path."

    Of course you will be able to develop your own startup as well, if you take the "Skip the backend" course after this course.

  4. Course 5: Front-end-Framework-Equipped Modern Front-end Developer (Choose either React, Angular, Backbone, OR Ember)

    We will help you choose the best front-end framework for you. Don't waste time learning a front-end framework that's not for you.

    Advanced front-end developers with experience using at least one of the four noted front-end frameworks are undoubtedly the hottest (highly sought after) developers today. They make between $70K and $160K+. (Salary varies by city and developer's expertise and experience.)

  5. Course 6: The Modern Full-stack Developer

    Learn the technologies you need to know to become a qualified and successful full-stack JavaScript developer.

    What You Will Learn
    You will learn all the tools, skills, and technologies necessary to become a full-stack JavaScript developer.

    Who Is this Course For?
    — Completed the first three courses

    What Will Graduating from This Course Allow You to Do?
    You will be in high demand as a full-stack JavaScript developer, making between $70,000 and $160,000+ a year. You will be able to develop any kind of startup comfortably. (Salary varies by city and developer's expertise and experience.)

  6. Other courses are coming later, including a "Skip-the-Backend" course, courses on developing mobile apps for iOS and Android using JavaScript, and a course on developing iOS apps using Swift and other Apple technologies.

What Can You Do Right Now?

  1. First, enter you email in the "Receive Updates" form above.
  2. Then, use the Contact form to (a) request features, (b) make suggestions, or (c) ask questions. We want to make our courses the best courses, the best value, the most rewarding. We need your help to do that.

When Specifically Will the Courses Begin?

We will release the course web site, with more detailed information, in about 3–4 weeks (most likely in January). You can enroll in classes then.

The first set of courses may begin to roll out in February.

How Much Will Each Course Cost?

While we haven't finalized the cost for each course, I do know that we have different prices for the courses. For example, Course 1 will cost less than the Front-end course. Moreover, the cost per course will definitely be affordable to the working class. I will make certain the courses are affordable for most people. I will fight to keep Course 1 under $200, though I can't promise that I will win.

Get Ready! Between now and Christmas, enjoy the down time because, when our courses begin, they will kick your butt into web-dev shape. So get ready to work hard, build cool stuff, change the world (you will), and realize your dreams.

Leave a Reply

Current ye@r *