Scope in JavaScript

Here’s a simple question:

<script>
    var str1 = "hello";
    var str2 = "world";

    function t1() {
        console.log(str1);
        console.log(str2);

        var str2 = "The fat." ";
        console.log(str2);
    }
	
	// What is output here?
    t1();

</script>
Copy the code

This is a very simple JS scope problem, but the more you emphasize the simple word, the more easy to make people relax, so lead to some students without thinking of the answer output

  • hello
  • world
  • Fat in

But the result is the output

  • hello
  • undefined
  • Fat in

So why is undefined? It should be world. The function contains str2, but str2 is undefined when I run to console.log(str2)

## lexical analysis

To know is to know, so let’s look at a few more examples

Example 1

<script>
    function t(userName) {
        console.log(userName);// What is output here?

        function userName() {
            console.log('tom');
        }
    }
    t('fat in');
</script>
Copy the code

What is the result of the output, this example seems to be different from the above, there is a kind of return to high school mathematics, question type change meng forced feeling, this time may be some students feel fat, but the actual output is

function userName() {
    console.log('tom');
}
Copy the code

Why function? In fact, this scope of the problem, can be obtained through the “set of formulas”, this formula, is JS lexical analysis,JS function before the execution of a job must be done is lexical analysis, so what exactly to what? Analyze the parameters, analyze the variable declarations, analyze the function declarations, so let’s use this problem to do the formulas

When executing t(‘ fat Dynasty ‘), there will be two stages, one is the analysis stage, and then the execution stage

Analysis stage:

  • At the moment when the function runs, an Active Object (hereinafter referred to as AO Object) will be generated. All variables that can be found in the scope of a function are on the AO. At this point, the code is expressed as: t.ao = {}

  • Analysis parameter: receive parameter, take parameter name as attribute, parameter value as attribute value, because there is no parameter, so the analysis result is represented by code: t.ao = {userName: fat direction}

  • Var declaration: there is no var declaration in t function

  • If the AO has an attribute with the same name as the function name, it will be overwritten by the AO. In the JS world, the function is also a type of variable. function userName() {console.log(‘tom’); }}

Execution stage:

Function userName() {console.log(‘ Tom ‘); function userName() {console.log(‘ Tom ‘); }

Example 2

<script>
    function t(userName) {
        console.log(userName);// What is output here?

        var userName = function () {
            console.log('tom');
        }
    }
    t('fat in');
</script>
Copy the code

So what’s the output here? This seems to be different from the above example, again into the muddled state? Don’t be afraid to go to the trouble and follow the formula one more time (the above example is written in detail, the following analysis is written briefly).

Before we analyze this, we need to understand two concepts, one is called a function declaration and the other is called a function expression

// This is called a function declaration
function userName() {
	console.log('tom');
}

// This is called a function expression
var userName = function () {
    console.log('tom');
}
Copy the code

Analysis stage:

  • Create AO object, t.ao = {}

  • T.ao = {userName: fat}

  • Parsing the var declaration: On the AO, form a property with the variable name of var as the property name and the value as undefined :t.AO = {userName : }; undefined};};};};};};};};};};};};};};};};} O = {userName: fat}

  • Parsing function declarations: There are no function declarations at this time, skipped

Execution stage:

Call t.ao.user name, so the final output is fat

Example 3

<script>
    t();
    t2();

    function t() {
        console.log('fat in');// What is output here?
    }

    var t2 = function () {
        console.log('hello fat in');// What is output here?
    };
</script>
Copy the code

So let’s look at one more example, this is totally back to high school, I did two examples and I feel like I got it, and you’re going to look at this on the exam?

The answer is that t() output is fat, and T2 () gives an error. Why is that?

  • T () can be called because the analysis of t function has been completed during the lexical analysis process, so it can be called

  • T2 () cannot be called because during the lexical analysis phase, there is a t2 declaration that only forms an attribute on the AO, but the value is undefined

Example 4

<script>
    function t(userName) {
        console.log(userName);// What is output here?
        function userName() {
            console.log(userName);// What is output here?
        }
        userName();
    }
    t('fat in');
</script>
Copy the code

Function within function, this time unexpectedly and the previous is not the same… I’m not going to say the answer this time, but I’m going to go through the formula

T (‘ fat dynasty ‘) analysis and implementation phase

Analysis stage:

  • Create AO object, t.ao = {}

  • T.ao = {userName: fat}

  • UserName = {userName: fat} var {userName: fat}

  • T.ao = {userName: function userName() {console.log(userName); }}

Function userName() {console.log(userName); function userName() {console.log(userName); }}

Analysis and execution of userName()

There are also two concepts to be clear here

// execute userName()
function () {
  console.log(userName);
};

/ / instead
var userName = function () {
    console.log(userName);
};
Copy the code

Analysis stage:

  • Create an AO object,userName.AO = {}

  • Analysis parameters: None

  • Var declaration: None

  • Analysis function declaration: None, skipped

Execution stage: Function userName() = function userName(); function userName() = function userName(); {console.log(userName); }}

Example 5

<script>
    function t(userName) {
        console.log(userName);// What is output here?
        var userName = function () {
            console.log(userName);// What is output here?
        }
        userName();
    }
    t('fat in');
</script>
Copy the code

Okay, I promise this is the last one… What is the output? As long as we’re sure that the formula works, we’ll get the answer, so let’s go with the formula

T (‘ fat dynasty ‘) analysis and implementation phase

Analysis stage:

  • Create AO object, t.ao = {}

  • T.ao = {userName: fat}

  • UserName = {userName: fat} var {userName: fat}

  • Analysis function declaration: None, skipped

Run console.log(userName). Var = {userName: = {userName: = {userName: = {userName: = {userName: = {userName: = {userName: = {userName: = {userName: = {userName: =}} function() {console.log(userName); }}, the code continues to execute, and then the userName() is executed.

Analysis and execution of userName()

Analysis stage:

  • Create an AO object,userName.AO = {}

  • Analysis parameters: None

  • Var declaration: None

  • Analysis function declaration: None, skipped

Function () {console.log(userName); function () {console.log(userName); }

conclusion

The JavaScript scope looks for its own AO first, and if it can’t find it, it looks for the AO of the parent function. If it can’t find the AO of the parent function, it looks for the AO of the higher level until it finds the Window. This forms a chain, and the AO chain is the scope chain in JavaScript.