1 Execution environment (execution context) : The execution environment is an object.

The global execution environment is the Window object, and every function also has its execution environment.

3 There are variable objects in the execution environment. The variable object holds all variables and functions defined in the execution environment.

4 The function’s internal property [[Scope]] holds the ** Scope chain, which is pre-created when the function is created. The execution environment of a function also has scope chains, which are created when the function is called, copied the scope chain of the function and prefixed to the variable object of the execution environment of the function (the active object).

5this is an internal property of the function, not of the execution environment. When a function is called, the live object automatically acquires its value.

6 Environment stack: the JavaScript program starts to run, creating a space where the data structure is the stack, called the environment stack.

The most initial element of the stack is the global execution environment, which is created during a function call and pushed onto the stack. After the function is executed, the execution environment is removed from the stack.

There are many execution environments in the environment stack, and the execution environments have their own variables defined, so the access permissions and order of variables and functions need to be regulated by a certain mechanism, that is, the scope chain.

Scope chain: organize variable objects in each execution environment with chained data deconstruction.

The scope chain of an execution environment is preceded by a variable object from the current execution environment, followed by a variable object from the external (containing) environment. Suppose the global execution environment calls function 1, function 1 calls function 2,

var color="yellow"
function f1(){
	console.log("f1",color);
	f2()
	function f2(){
		console.log("f2",color);
	}
}
f1()
Copy the code

Then the scope chain can be expressed as:

8 variable access mechanism: Based on the scope chain, when accessing a variable, the search will be conducted along the node by node of the scope chain, and the search will be stopped when the variable is found.

How to understand the execution environment of the function when the object method is called?

Var color="yellow" var obj={color:"blue", f1:function(){console.log(color)}} obj.f1()Copy the code

So a function is called as a method of an object in the same way that a function is called as a function. In the above example, the variable object of obj.f1() does not find the color variable, so it finds the variable object of the global execution environment along the scope chain.

I think it’s easier to understand the understanding that this points to by separating it from the execution environment and scope chain. This has nothing to do with the execution environment, only who called the function. The value of this is undefined until the function is called. This refers to whoever called the function. As you can see from the following code, the function’s this reference is not necessarily related to the execution environment.

Var color="yellow" var obj1={color:"blue", f1:function(){console.log(this.color)}} obj1.f1(Copy the code

Closures: Closures are functions that have access to variables in the scope of another function. A common way to create closures is to create another function inside a function.

function createCompareFunction(propName){ return function(obj1,obj2){ var value1=obj1[propName]; var value2=obj2[propName]; if(value1<value2){ return -1 }else if(value1>value2){ return 1 }else{ return 0 } } } var Var result=compare({name:"Nicholas"},{name:"Greg"}) //2, compare=null //3, eliminate anonymous function referencesCopy the code

After 1createCompareFunction returns, its execution environment and its scope chain are destroyed, but the variable object (activity) is saved because the anonymous function’s environment object is still referenced by the closure’s chain.

(2) After code 3 destroys compare, its variable object is actually reclaimed.

CreateCompareFunction leaves only the variable object, which stores the last mirror image of the variable when the function completes. The following code expects result[0] to return 0 and result[9] to return 9, but not as expected.

function createFunctions(){ var result=new Array(); for (var i=0; i<10; i++){ result[i]=function(){ return i } } return result } var result=createFunctions()Copy the code

ƒ (){return I} after the call is complete, createFunctions contains the values of result and I, and the result array contains 10 functions, each of which has the form ƒ (){return I} with the last value of 10.

Result [0]() // Output is 10Copy the code

When called, I is not found in the function’s own active object, so I is found in createFunctions. Each element in result is 10. To do so, this is the code below.

function createFunctions(){ var result=new Array(); for (var i=0; i<10; i++){ result[i]=function(num){ return function(){ return num; }; }(i) } return result }Copy the code

To understand this code, this is important: “The function’s internal property [[Scope]] holds the Scope chain, which is created in advance when the function is created. The function execution environment also has scope chains, which are created when the function is called, copied the function’s scope chain and prefixed to the variable object (active object) of the function’s execution environment.

The innermost closure function(){return num} has two outer functions. When a closure is created, it already has a scope chain. This scope chain contains only the variable objects of the outer function, not its own.

In the code above. The result array contains 10 closure functions, each of which is in the form of ƒ (){return num}. The variable object of the outer function along the scope chain is different from each other, and num is different, fulfilling the expectation.

11 No block-level scope

The scope is global and function level only, the code block has no scope, so the code block execution also has no execution environment on and off the stack destruction concept. In the following code, the variable I is stored in the variable object of the output() function and is also accessible outside the for loop.

function output(){ for(var i=0; i<10; I ++){console.log(I)} console.log("outside for statement", I)Copy the code

To mimic block-level scopes, you can place block-level scopes in anonymous functions and call them immediately, using the following form. The function call has the concept of the execution environment on and off the stack destruction. Finally, after the function is executed, the execution environment destruction and variable object destruction can avoid the problem that variables pollute the global execution environment.

Function output(){(function(){for(var I =0; i<10; i++){ console.log(i); }}) (); Console. log("outside for statement", I) // Uncaught ReferenceError: I is not defined}Copy the code

12 Extend scope chain — with statement (not allowed in strict mode)

var obj={
	name:"Alice",
	age:20,
}
console.log(obj.name,obj.age)
Copy the code

Is equivalent to

with(obj){
	console.log(name,age)
}
Copy the code

The variable object of the with statement contains all the attributes of obj (name, age), and the with statement can extend the scope chain. In the following code, the variable object of with is added to the front of the variable object of f, which is in the scope chain: variable object of with > variable object of f -> global environment variable object. So the with statement can use hobby in f, and of course f can use desc in the with variable.

function f(){
	var obj={name:"Alice",age:20};
	var hobby="singing";
	with(obj){
		var desc=name+age+hobby
	}
	return desc
}
Copy the code