Article Reference:

Time.geekbang.org/column/arti… Github.com/mqyqingfeng…

Execution context

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

The call stack

The call stack is a mechanism by which the javascript engine keeps track of the execution of functions so that it can understand the calling relationships between functions. Javascript uses the stack as a data structure to manage execution context.

var a = 0;

function add(a + b) {
	returan a + b;
}

function sum(c) {
	return c + add(2.3);
}

sum(a);


Copy the code

The above code executes the call stack as follows:

As you can see, a stack overflow can occur if the call stack fails to exit in an orderly manner. This usually happens when there are problems with recursive call termination conditions, etc.

Block-level scope

A scope determines the accessibility of variables and other resources in a code block.

Before ES6, javascript had no block-level scope, only global scope and function scope. Var, let, and const are the three key words of JS variable definition, among which var, let, and const are fundamentally different. Let and const are es6 grammars. Both support block-level scope, and there is no variable promotion: declarations are not placed at the top of the code during recompilation. In javascript, the concept of lexical environments was introduced in order to add block-level scope. We can simply say that variables declared by var and function are added to the environment variables, while variables declared by let and const are added to the lexical environment.

We can analyze the difference between these two variables by creating a function.

function strong(){
  var a = 1;
  let b = 2;
  {
    var c = 3;
    let d = 4;
    console.log(c)
    console.log(d)
  }
  console.log(a)
  console.log(b)
  console.log(c)
}

foo()
Copy the code

When the function is created and executed, the following call stack is generated:

When console.log(c) is executed, the call stack looks like this:

As you can see, block-level scoped variables like let, const, and so on are put directly into the lexical environment, first looking for the variable here, if not in the variable environment. After the block-level code is executed, these variables are popped directly into the lexical environment stack.