This is the 8th day of my participation in the August Challenge. Check out the August Challenge for more details

preface

JavaScript has a feature called Scope. The concept of scope is not easy for many new developers to understand, but it also ties in with the familiar concept of closures. This article will explain scopes and scope chains in the simplest and most understandable way possible, which I hope will be helpful.

What is scope?

Scope is the area of a program’s source code where variables are defined.

A scope specifies how to find a variable, that is, determine what access the currently executing code has to the variable. In other words, a scope determines the visibility of variables and other resources in a block of code. You may not know what scope means. Let’s go the other way:

The term scope sounds fancy, but it’s actually pretty simple to understand.

Think of it as the concept of turf awareness, where the variable is the star.

Some variables are recognized only in their own domain, functions; Some variables are like Big Hollywood stars, with influence in every corner of the program.

Everything depends on how the variable is declared where it was born.

The Scope of a variable is called the Scope of the variable.

Let’s think about it in terms of code

function sayHi() {
    var myName = 'Dream Chasers';
    console.log('Hello,' + myName);
}
sayHi(); // Execute sayHi to print "Hello dreamers"
console.log(myName); // Uncaught ReferenceError: myName is not defined
Copy the code

Running the code above, we can see that an error will be reported when printing myName. This is because the variable myName is not declared in the global scope, so it will be reported when fetching myName in the global scope. The myName variable can only be used in function scope, not global scope.

We can understand it as:

A scope is an independent domain that keeps variables from leaking and being exposed. In other words, the greatest use of a scope is to isolate variables. Variables of the same name in different scopes do not conflict.

What are the scopes?

So what are the JavaScript scopes?

Before ES6, JavaScript had no block-level scope, only global scope and function scope. With the advent of ES6, we have “block-level scope “, which can be represented by the addition of the let and const commands.

There are three types of scope:

  • Global scope – Jackie Chan brother
  • Function scope – Hong Kong comedy Uranus
  • Block-level scope – at school, the mic of KTV in class “commensitivity”

Global scope

Variables declared outside the top-level scope of any function are global variables, and such variables have global scope.

As noted above, variables include functions declared using the var declaration and the function keyword.

var name = 'Dream Chasers'; // Variables in the global scope

// Function scope
function showName() {
    console.log(name);
}

// block scope
{
  name = 'experts'
}

showName(); // Output "brick"
Copy the code

In the example above, we can see that global variables are available in the global, function, and block-level scopes.

All variables that do not define a direct assignment are automatically declared to have a global scope

function sayHi() {
    myName1 = 'experts';
    var myName = 'Dream Chasers';
    console.log('Hello,' + myName);
}
sayHi(); // Execute sayHi to print "Hello dreamers"
// console.log(myName); // Uncaught ReferenceError: myName is not defined
console.log(myName1); // ""
Copy the code

All properties of a Window object have global scope In general, the built-in properties of a Window object have global scope, Such as window. The name, the window. The location, the window. The top, Windows.. The navigator userAgent, etc.

console.log(navigator.userAgent);
console.log(window.navigator.userAgent);
// Both of the above printed results are "Mozilla/5.0 (Windows NT 10.0; Win64; X64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36"
Copy the code

Function scope

There is a downside to global scopes

If we write a lot of JS code in which variable declarations are not included in functions, then they are all in global scope. This can pollute the global namespace and cause naming conflicts or overwriting.

// Write the code by zhang SAN
var myName = 'Dream Chasers';

// The code is written by Li Si
var myName = 'experts';
Copy the code

Function () {//… function() {//… }) (). This is actually a representation of the scope of the function.

The immediate function creates a separate scope for variables that cannot be accessed outside the scope to avoid “variable contamination”.

A variable defined inside a function that has a function scope.

var name = 'Dream Chasers'; // Name is global
function sayHi1() {
    // myName is defined as a function scope variable
    var myName = 'experts';
    console.log('Hello,' + myName);
}

function sayHi2(name) {
    // Name is the parameter passed to sayHi2, which is a local variable
    console.log('Hello,' + name);
}

sayHi1(); // "Hello, brick"
sayHi2(name); // "Hello, dream chaser"
console.log(myName); // Uncaught ReferenceError: myName is not defined

{
    console.log(myName); // Uncaught ReferenceError: myName is not defined
}
Copy the code

MyName is a variable defined inside a function, so it is “locked” and can only be accessed inside the function scope. It is not accessible from the global or block-level scope, and will be accessed with an error.

Block-level scope

A block-level scope is a piece of code wrapped in braces, such as a function, a judgment statement, a loop statement, or even a single {} can be considered a block-level scope.

Starting with ES6, we added let and const, the keywords that declare variables. The variables defined by these two keywords, if wrapped in braces, can then be treated as a block-level scope.

Block-level scopes are created when:

  • Inside a function
  • Inside a code block (enclosed by a pair of curly braces)
{
    let myName = 'Dream Chasers';
    console.log(myName); // "dream Chasers"
}

console.log(myName); Uncaught ReferenceError: myName is not defined

function sayHi() {
    console.log('Hello,' + myName); Uncaught ReferenceError: myName is not defined
}
sayHi(); // Execute the sayHi function
Copy the code

In the above example, we can see that a variable in a block scope is not accessible as long as it is outside the code block in which it is defined. This is similar to function scopes — they only work “on their own turf”, so they are collectively referred to as “local scopes”.

The scope chain

The scope covers the scope, and you have the scope chain

Nesting of scopes occurs when a block or function is nested within another block or function. Like this:

var hello = 'hello';
function init() {
    var name = "Mozilla";
    function sayHello() {
        console.log(hello, name);
    }
    sayHello();
    console.log(myName); / / an error
}
init();
Copy the code

In the example above, there is the init function scope, the sayHello function scope, and the global scope. Their relationship is shown as follows:

When sayHello is called, console.log(hello, name) is executed; The sayHello function does not declare hello and name. The sayHello function does not declare hello and name. So you can’t find it at first.

What do I do to find Hello and Name? Understandably, at this point, the JS engine pokes its head out, goes to the upper scope (init), finds the name, and is ready to use.

Hello is not found in the init function scope, so the JS engine will continue to “poke its head” into the upper scope (global scope), find the Hello variable, and use it directly.

Why do I get an error when I print myName? Because the init function scope, found no variables myName, so JS engine “go out,” go to the upper scope (global scope), found no myNam, and global scope has no head leaned out, the upper scope), rest, an error!

In this search process, a scope chain is formed by successive layers of scope, and the scope chain relationship is shown as follows:

Of course, the scope chain mentioned above is not very in-depth. We will go into variable objects and then understand the mechanism of scope chain.

reference

  • In-depth understanding of JavaScript scopes and scope chains
  • Understand scopes from a compilation principle perspective
  • Day5: Tom Cruise and Tom Cruise — Scope of variables (1)
  • Day6: Tom Cruise and Tom Cruise — Scope of variables (2)

If there are any mistakes in this article, please correct them in the comments section. If this article helped you or you liked it, please like it and follow it.