There is a very classic Ali interview question, the original question is as follows:

        var x = 1;
        function func(x, y = function () { x = 2 }) {
            var x = 3;
            y();
            console.log(x);
        }
        func(5)
        console.log(x);
Copy the code

The output is 3,1. I was confused for a long period of events, and also looked at many articles on the Internet, feeling that the description is not transparent enough. Here’s a step – by – step look at how browsers work.

Var x = 1 in the global context; And the console. The log (x); The essence is for its confusing effect, which will not be explained.

As you probably know, functions generate their own private context during execution to protect their private variables from the outside world. Var (x); var (x); var (x); So what x should we print at the end?

There is a more complex mechanism involved.

  1. Function has ES6 parameter assignment defaults (whether valid or not)
  2. An operation to declare a variable based on var/let/const occurs in the function body

As long as both of these conditions are met, the function produces two contexts during execution. The private context generated by a function (completion by performing a cloze parameter assignment) & the block-level context generated by a function body as a code block (whose parent context is the private context of the function). Interested readers can view both contexts from the debugger’s console.

Obviously, the function in this problem satisfies both of the above conditions. The function generates its own private context at the beginning of execution. After the parameter is assigned, that is, x = 5; y = function () {x = 2}; After that, the function body is treated as a code block, generating a new block-level context. The scope of this block-level context is the function’s private context. Ignoring the variable promotion phase and so on, there is a private variable X with a value of 3 in the last block-level context. Y is executed in a block-level context, but it is created in the function’s private context and is scoped to the function’s private context. Y execution, because y does not have its own private variable x, according to the scope chain to its parent context search. x = 2; The time is to change the value of x in the function’s private context to 2. X is then printed in the block-level context. The block-level context has its own private variable X with a value of 3. So the output is also 3.

These steps can also be viewed directly from the console through the Debugger.

I hope this article has been helpful.