Can javascript be executed directly? Where is javascript executed?

This article mainly introduces where javascript can be executed in the following places. It has certain reference value and friends in need can refer to it. I hope you will gain a lot after reading this article. Let the editor take you to understand it together.

During the running of JavaScript, we often encounter some “strange” behaviors, and we don’t understand why JavaScript works like this. At this time, you may need to understand the relevant content during JavaScript execution and the usage of python for statement.

1. Execution context

There are three code execution environments in JavaScript:

  • Global Code: The default environment where JavaScript code starts running
  • Function Code: Code goes into a JavaScript function
  • Eval Code: Use eval() to execute code

In order to represent different running environments, JavaScript has the concept of execution context (Execution context, EC). In other words, when JavaScript code is executed, it will enter different execution contexts, and these execution contexts constitute an Execution context stack (Execution context stack, ECS).

For example, the following JavaScript code:

var a = "global var";

function foo(){
    console.log(a);
}

function outerFunc(){
    var b = "var in outerFunc";
    console.log(b);
    
    function innerFunc(){
        var c = "var in innerFunc";
        console.log(c);
        foo();
    }
    innerFunc();
}
outerFunc()

The code first enters the Global Execution Context, and then enters the execution context of outerFunc, innerFunc and foo in sequence. The execution context stack can be expressed as:

When JavaScript code is executed, the first one that enters is always the default Global Execution Context, so it is always at the bottom of ECS.

There are three important properties for each Execution Context, Variable object (Variable object, VO), Scope chain (Scope chain) and this. These three attributes have a very important relationship with the behavior of code running, and will be introduced one by one below.

Of course, in addition to these three properties, Execution Context can also have some additional properties according to implementation needs.

2. Variable object

As you can see from the above, in the Execution Context, the variable object (VO) will be saved. Let’s take a look at what the variable object is.

Variable objects are data scopes associated with the execution context. It is a special context-related object that stores variable and function declarations defined in the context. In other words, generally VO will contain the following information:

  • Variable (var, Variable Declaration);
  • Function Declaration (FD);
  • function parameters

When JavaScript code is running, if it tries to find a variable, it will first look for VO. For the code in the previous example, the VO in the Global Execution Context can be expressed as follows:

3. Activation object

Only the variable object of the global context is allowed to be accessed indirectly through the attribute name of VO; In the function execution context, VO cannot be accessed directly. At this time, the object is activated by (Activation Object, abbreviated as AO) plays the role of VO. The activation object is created when entering the function context and is initialized through the arguments attribute of the function.

Arguments Objects are internal objects in the activation object AO in the function context. It includes the following properties:

  • callee: a reference to the current function
  • length: the number of parameters actually passed
  • properties-indexes: It is the parameter value of the function (arranged from left to right in the parameter list)

The relationship between VO and AO can be understood as that VO will behave differently in different Execution Contexts: when in the Global Execution Context, you can use VO directly; however, in the function Execution Context, AO will be created.

When the above example starts executing outerFunc, an AO of outerFunc will be created:

Through the above introduction, we now understand what VO and AO are and the relationship between them. Next, you need to see how the JavaScript interpreter executes a piece of code and sets VO and AO.

4. Take a closer look at the Execution Context

When a piece of JavaScript code is executed, the JavaScript interpreter will create an Execution Context. In fact, there are two stages here:

  • Creation phase (when the function is called, but before executing the code inside the function)
    • Create scope chain
    • Create VO/AO (variables, functions and arguments)
    • Set the value of this
  • Activation/Code Execution Phase
    • Set the values of variables, references to functions, and then interpret/execute the code

Here I would like to introduce some details in “Creating VO/AO” in detail, because these contents will directly affect the behavior of code running.

For the “Create VO/AO” step, the JavaScript interpreter mainly does the following things:

  • Create and initialize the arguments object according to the parameters of the function
  • Scan function internal code to find function declaration (Function declaration)
    • For all found function declarations, store the function name and function reference in VO/AO
    • If there is already a function with the same name in VO/AO, then it will be overwritten.
  • Scan the internal code of the function to find variable declarations (Variable declaration)
    • For all found variable declarations, store the variable name in VO/AO and initialize it to “undefined”
    • If the variable name is the same as an already declared formal parameter or function, the variable declaration does not interfere with the existing attributes of this type.
5. Example analysis

I introduced so much theoretical knowledge such as Execution Context, VO/AO, etc., of course, to facilitate us to analyze some behaviors in the code. Here, we will analyze the results through a few simple examples and combine the above concepts.

5.1
(function(){
    console.log(bar);
    console.log(baz);
    
    var bar = 20;
    
    function baz(){
        console.log("baz");
    }
    
})()

Running the code in Chrome will output:

Code explanation: The anonymous function will first enter “Create Result”, the JavaScript interpreter will create a “Function Execution Context”, and then create Scope chain, VO/AO and this. According to the previous introduction, the interpreter will scan function and variable declarations, and the following AO will be created:

So, for bar, we will get the output “undefined”, which shows that we accessed a variable before declaring it. This is “Hoisting” in JavaScript.

5.2

Continuing with the above example, make some modifications:

(function(){
    console.log(bar);
    console.log(baz);
    
    bar = 20;
    console.log(window.bar);
    console.log(bar);
    
    function baz(){
        console.log("baz");
    }
    
})()

Running this code will get the “bar is not defined(…)” error. When the code is executed to “console.log(bar);”, it will search for “bar” in AO. However, according to the previous explanation, “bar” in the function is not declared through the var keyword, so it will not be stored in AO, so this error occurs.

Comment out “console.log(bar);” and run the code again, you can get the following results. “bar” is created during the “activation/code execution phase”.

5.3
(function(){
    console.log(foo);
    console.log(bar);
    console.log(baz);
    
    var foo = function(){};
    
    function bar(){
        console.log("bar");
    }
    
    var bar = 20;
    console.log(bar);
    
    function baz(){
        console.log("baz");
    }
    
})()

The result of running the code is:

The most “strange” part in the code is probably the output of “bar”. The first time is a function, and the second time is “20”.

In fact, it is easy to explain. Going back to the previous introduction to “Create VO/AO”, during the process of creating VO/AO, the interpreter will first scan the function declaration, and then "foo: \ " is saved in AO; but when the interpreter scans the variable declaration, it finds "var bar = 20;", but because "foo" already exists in AO, there is no operation .

However, when the code is executed to the second sentence “console.log(bar);”, the “activation/code execution phase” has already reset the “bar” in AO.

6. Summary

This article introduces the execution context (Execution Context) in JavaScript, as well as concepts such as VO/AO, and finally uses several examples to demonstrate the importance of these concepts to our understanding of JavaScript code execution.

By understanding the specific details of VO/AO’s “creation phase” and how to scan function declarations and variable declarations, you can have a clear understanding of “Hoisting” in JavaScript. Therefore, understanding the behavior of the JavaScript interpreter and related concepts is very helpful in understanding the behavior of JavaScript code.

The Scope chain and this in Execution Context will be introduced later.