Variable scope and variable promotion in javascript are described in detail

  • 2020-03-26 21:39:01
  • OfStack

Variable scope
"The scope of a variable indicates the context in which the variable exists. It specifies which variables you can access and whether you have permission to access a variable.

Variable scope is divided into local scope and global scope.

Local variables (scope at the function level)
Unlike other programming languages for opposite objects (C++, Java, etc.), javascript has no block-level scope (surrounded by curly braces); However, javascript has function-level scope, meaning that variables defined within a function can only be accessed within the function or within the function (except for closures, which we'll cover in a few days).

An example of a 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
//      Don't forget to use the var keyword
//      If you declare a variable without the var keyword, it will be a global 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 a higher priority than global variables
//If a variable of what is in the global scope is declared again in the local scope, then when the variable is called in the local scope, the declared variable in the local scope is called first:
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

The global variable
All variables declared outside the function are in global scope. In a browser environment, this global scope is our Window object (or the entire HTML document).

Every variable declared or defined outside the function is a global object, so the variable can be used anywhere, for example:


// name and sex is not in any function
var myName = "zhou";
var sex = "male";

//They're all in the window object
console.log(window.myName); //paul
console.log('sex' in window); //true

If a variable does not use the var keyword when it is first initialized/declared, it is automatically added to the global scope.


function showAge(){
  //Age is initialized without the var keyword, so it is a global variable
  age = 20;
  console.log(age);
}

showAge();  //20
console.log(age); //Because age is a global variable, the output here is also 20

The functions in setTimeout are executed in global scope

The function in setTimeout is in the global scope, so when this keyword is used in the function, it refers to the global object (Window) :


var Value1 = 200;
var Value2 = 20;
var myObj = {
  Value1 : 10,
  Value2 : 1,

  caleculatedIt: function(){
    setTimeout(function(){
      console.log(this.Value1 * this.Value2);
    }, 1000);
  }
}

myObj.caleculatedIt(); //4000

To avoid global scope contamination, we generally declare as few global variables as possible.  
Variable ascension (Variable Hoisting)
All variable declarations are raised to the beginning of the function (if the variable is inside the function) or to the beginning of the global scope (if the variable is a global variable). Let's take a look at an 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
}

The function declaration overrides the variable declaration
If there are function declarations and variable declarations (note: declarations only, not assigned) and the variable name is the same as the function name, they are prompted to the beginning of the outer scope, but the function has a higher priority, so the value of the variable is overwritten by the function.


// 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

However, if the variable or function is assigned, the other one cannot override it:


// 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

Finally, in strict mode, assigning a variable without first declaring it will result in an error!


Related articles: