The author nonsense

Recently, I have been trying to consolidate my basic knowledge for future interviews in big cities

Many interviews will also find that many of them will involve problems that they do not care about in their daily work, and then they will occasionally share with the same friends the interview knowledge points that they do not contact in their daily work but are often asked about

Variable promotion?

This is a question that anyone who has just graduated from a job interview would be comfortable with, but we’ve taken a step at it with two very common and very basic interview questions. (As a beginner, I often get confused.)

    function fun () {}
    var fun = 'fuck bitch'
    console.log(fun) / /???
Copy the code
    console.log(fun) / /???
    function fun () {}
    var fun = 'fuck bitch'
Copy the code

All the big boys would say is, it’s too easy.

  1. First of all, the first one saysfunck bitchThis does not involve variable promotion, just overwriting the variable with the same name.(Note: This happens during execution)
  2. And then, problem number two, outputƒ () {}For specific reasons, we will talk about the well-known knowledge of variable promotion

We’re used to var a = 2; As a statement, which the JavaScript engine does not. It treats var a and a = 2 as two separate declarations, the first for the compile phase and the second for the execution phase.

This means that no matter where the declaration in scope appears, it will be processed first before the code itself is executed. This process can be visualized as all declarations (variables and functions) are “moved” to the top of their scope. This process is called promotion.

The declaration itself is promoted, but assignment operations, including assignment of function expressions, are not.

Refer to the address

This can explain why Fun did not return an error, but many beginners like me will ask why ƒ () {} is displayed instead of undefined or fuck bitch

For this kind of problem, according to my previous understanding. In my mind, executing code is

function fun () {}
console.log(fun) // --> fun(){}
fun = 'fuck bitch'
Copy the code

But if you ask me why this is the case, I don’t know why.

Why does it happen?

I do not know whether the students have thought of such a question, was generally just for the interview and to take a glance to say why it is ok. But that’s not enough to be the senior bald cape-maker of the future.

This brings us to the knowledge of variable objects that execute context in the javascript language

When JavaScript code executes a executable code, an execution context is created.

The life cycle of an execution context can be divided into two phases.

  1. Create a stage

In this phase, the execution context creates the variable object, establishes the scope chain, and determines what this refers to.

  1. Code execution phase

Once the creation is complete, the code is executed, which is when variable assignments, function references, and other code are completed.

Variable Object

The creation of a variable object, in turn, goes through the following process.

  1. Create arguments objects. Examine the parameters in the current context and establish the properties and property values under the object.
  2. Check for function declarations in the current context, that is, functions declared using the function keyword. Creates an attribute with the name of the function in the variable object and the value of the attribute is a reference to the memory address of the function. If an attribute of the function name already exists, the attribute will be overridden by a new reference. (Commonly said functions are promoted preferentially, and the same name will cause overwriting)
  3. Check for variable declarations in the current context (undeclared not defined). For each variable declaration found, create a property in the variable object with the name of the variable, and the value of the property is undefined. If the attribute of the variable name already exists, it will be skipped to prevent the function with the same name from being changed to undefined. The original attribute value will not be changed.

Comparing the two questions and combining the description, we can understand the specific implementation principle:

    function fun () {}
    var fun = 'fuck bitch'
    console.log(fun) // 'fuck bitch'
Copy the code

Because fun = ‘fuck bitch’ is run during execution in the execution context and does not generate overrides, the skip operation is in the creation phase, so the output will naturally be Fuck Bitch.

And problem number two

    console.log(fun) // fun () {}
    function fun () {}
    var fun = 'fuck bitch'
Copy the code

Since function is promoted first, and fun () {} is not overridden at creation because it has the same name, output fun () {}. The details are the same as below.

// The execution sequence of the preceding example is

// First put all function declarations into variable objects
function fun () {}

// Next, put all variable declarations into variable objects, but since fun already has a function of the same name, the assignment of undefined is skipped at this point
// var fun = undefined;

// Then start executing the code in the execution phase
console.log(fun); // function fun
fun = 'fuck bitch';
Copy the code

Such an explanation, feel oneself force case instant rose a class? !

Further develop

Now, before we get too excited, let’s just go through this step by step for another example just to make sense of it.

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

    var a = 1;
    function foo() {
        return 2;
    }
}

test();
Copy the code

VO AND AO

In the function context, we use activation Objects (AO) to represent variable objects.

Properties in a variable object (VO) cannot be accessed until it is executed! However, after the execution phase, the variable object (VO) is transformed into an active object (AO), in which all properties can be accessed, and then the execution phase operation begins.

They are really the same object, but in different life cycles in the execution context.

According to the above example:// Create process
testEC = {
    // A variable object
    VO: {},
    scopeChain: {}
}

AO = {
    arguments: {... },// Note: Function arguments may not be in the arguments object in the browser presentation, so I've done this for ease of understanding
    foo: <foo reference>// foo's address refers to a: undefined}Copy the code
// Execution phase
VO ->  AO   // Activation Object
AO = {
    arguments: {... },foo: <foo reference>,
    a: 1,
    this: Window
}
Copy the code

For this reason, the execution order of the above example should be:

function test() {
    function foo() {
        return 2;
    }
    var a = undefined;
    console.log(a);
    console.log(foo());
    a = 1;
}
test();
Copy the code

Now increase the difficulty:

// demo2
function test() {
    console.log(1, foo);
    console.log(2, bar);

    var foo = 'Hello';
    console.log(3, foo);
    var bar = function () {
        return 'world';
    }

    function foo() {
        return 'hello';
    }
}

test(); // ??? 
Copy the code

Can be converted to

// demo2
function test() {
    function foo() {
        return 'hello';
    }
    // Next, put all variable declarations into variable objects, but since foo already has a function of the same name, the assignment of undefined is skipped
    // var foo = undefined;
    
    var bar = undefined;
    
    console.log(1, foo);
    console.log(2, bar);

    var foo = 'Hello';
    
    console.log(3, foo);
    
    bar = function () {
        return 'world';
    }
}

test(); 
ƒ foo() {
// return 'hello';
// }
// 2 undefined
// 3 "Hello"
Copy the code

That’s what I’d like to share with you. Endeavor, struggle. 💪 💪

reference

Variable object details

Delve into variable objects