This is the 9th day of my participation in Gwen Challenge

preface

We know that JavaScript has a pre-compile session, which takes place before the engine compiles the code and does some “piecing” of the code so it can be executed later. Precompilation often leads to two strange phenomena: variable declaration promotion and function overall promotion. Of course, these two sentences are only a simple summary, can not solve all the problems.

Today, I read the fourth chapter of the first volume of JS you don’t know, which makes me have a deeper understanding of “ascension”. So I write this article with this understanding and my previous knowledge of JS improvement

First, let’s look at two simple examples

First, let’s take a simple example. Will fn be executed?

fn();
function fn(){
  console.log("fn");
}
Copy the code

For a slightly more complicated example, what does the following code print?

function fn(){
    return f;
    f = 10;
    function f(){
        var f = 11; }}console.log(typeof fn());
Copy the code

The first answer is: yes, print fn; The second answer is: function

If you answered correctly, congratulations, you have a deep understanding of precompilation! Don’t be discouraged if you get it wrong. Keep reading with your questions and this article will give you answers

Understand what ascension is

In terms of what is ascension, I prefer to take it literally first, “lift” means to lift up, “lift” means to lift up, “lift” means to move up, so ascension probably means to move up. In JS, to understand promotion, I think there are a few things to understand:

  1. What is the thing that is being promoted, and where is the thing to be promoted?
  2. Why should there be promotion? What are the benefits?
  3. What is the principle and process of ascension?

Here are some of them:

What is it that we’re elevating? To where

I wrote about engines, compilers, and scopes earlier in this article:

The engine first compiles the JavaScript code before interpreting it, and part of the compilation phase is finding all the declarations and correlating them with the appropriate scope.

This mechanism is also at the heart of lexical scoping. To sum up both problems in one sentence, the compiler elevates all function and variable declarations to the top of their scope. So let’s go back to the first problem

fn();
function fn(){
  console.log("fn");
}
Copy the code

Since functions are processed before code is executed, the function is promoted to the top of its scope; So fn is accessible when it’s executing, so print fn

The benefits of ascension

The benefit of the upgrade is simply to make it easier for the engine to find variables when executing JavaScript code

JS upgrade the detailed process

Referring to the previous study notes and rearranging them, I summarize the detailed process of JS improvement as the following four steps:

  1. createAOObject; (Active Object, execution context)
  2. Find the parameter and variable declarations, and use the variable name and parameter name asAOThe property name of the object, with the valueundefined;
  3. Unify arguments and parameters;
  4. Find the function declaration (excluding the function expression) in the function body, using the name of the function declaration asAOThe property name of the object is suspended and the value is the function.

There are a few things to note about this process

  1. Both functions and variables are promoted, but variables are promoted declaratively, while functions are promoted overall and take precedence over functions
  2. Function expressions are not promoted
  3. Each scope is promoted, including the global scope

With that in mind, let’s look at problem number two

function fn(){
    return f;
    f = 10;
    function f(){
        var f = 11; }}console.log(typeof fn());
Copy the code

When fn executes, the scope of fn inside is roughly: (remember, why I said roughly?)

// this is the pseudo-code for the scope before fn executes
AO : {
  f : function f(){ var f = 11}}Copy the code

When fn is executed, the first thing inside it is “return f”, so fn returns f function, so typeof fn() returns “function”.

Two problems solved, let’s talk about why did I say roughly? In other words let’s talk about the nature of scope, what else is in scope?

Scope is essentially execution context, an execution context defines an environment execution environment, the function of each execution execution context is unique, so multiple calls a function will lead to create multiple execution context, when the function is performed, it is produced by the execution context will be destroyed.

Execution contexts are often chained, which we call scope chains. The specific representation of scope chain in JavaScript is [[scope]]. [[scope]] refers to what we call the scope chain, which is only accessible and called by the JavaScript engine. In function scope, there is not only the context AO, but also this, arguments, and so on. There are more global scopes, but generally, for convenience, when analyzing scopes, we don’t consider writing things that we don’t care about.

The above is a personal summary of JS promotion

Finally, a question to test your learning results

var a = 1;
function a(a){
    console.log(a)
    var a = 2
}
console.log(a)
a(3)
Copy the code

Give your answer first and it will appear in the comments section

END