29 Oct 2013

JavaScript Variable Scope & Hoisting Explained


javascript web design development php html5 css3 ajax

In this post, we'll learn JavaScript’s variable scope and hoisting and every one the idiosyncrasies of each.

It is imperative that we perceive however variable scope and variable hoisting work in JavaScript. These ideas might sound simple, however they're not. There are some necessary subtleties that we should understand, if we would like to achieve JavaScript development.

Variable Scope

A variable’s scope is that the context within which the variable exists. It specifies from wherever you'll access a variable and whether or not you have got access to the variable in this context.
Variables have either a local scope or a global scope.

Local Variables (Function-level scope) :
Unlike most programming languages, JavaScript doesn't have block level scope (variable scoped to close ringleted brackets); instead, JavaScript has function-level scope. Variables declared among a function ar local variables and ar solely accessible among that functions or by fuction within that function. See my post on Closures for a lot of 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 local variable before you use them. In fact, you must use JSHint to check code for syntax error and style guides. Here is the trouble with not declaring local variable:

// 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 constant name, the local variable can have priority after you plan to use the variable within 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 ar within the global scope. within the browser, that is what we are involved with as front-end developers, the global context or scope is that the window object (or the complete HTML document).
    • Any variable declared or initialized outside a function may be a global variable, and it's so obtainable to the complete 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;

      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

        • If a variable is initialized (assigned a value) while not initial being declared with the var keyword, it's automatically extra to the global context and it's so 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

          • setTimeout Variables are Executed in the Global Scope :
          Note that all of the functions in setTimeout are execut in global scope. This is a tricky; 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 wish to become a JavaScript master, that you definitely need to try and do (otherwise you'll be looking Honey Boo Boo right now), you've got to understand that it's necessary to avoid making several variables within the global scope, like 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 );
          }

          Variable Hoisting


          All variable declarations are hoisted (lifted and declared) to the highest of the function, if outlined in a very function, or the highest of the global context, if outside a function.

          It is vital to grasp that to understand variable declarations are hoisted to the highest, not variable initialisation or assignments (when the variable is allotted 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 highest of the containing scope. and function declaration takes precedence over variable declarations (but not over variable assignment). As is noted higher than, variable assignment isn't hoisted, and neither is function assignment. As a reminder, this is often a function assignment: var myFunction = function () .

          Here could be 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 good to note down that function expressions, such as the example below, are not hoisted.
          var myName = function () {
          console.log ("Rich");
          In strict mode, it's an error in case you assigned to variable a value without 1st declaring the variable. It is very better practice to always declare your variables.

          No comments:

          Post a Comment