# Analysis of composition function from the perspective of EC / VO / AO stack memory and scope

Time：2021-4-8

@[toc]

## 0 / warm up

``````function fun(n, o) {
console.log(o);
return {
fun: function (m) {
return fun(m, n);
}
};
}
var c = fun(0).fun(1);
c.fun(2);
c.fun(3);``````

Figure 3.7_ graphic

## Composition function in 1 / Redux

``````function compose(...funcs) {
if (funcs.length === 0) {
return arg => arg
}

if (funcs.length === 1) {
return funcs[0]
}

return funcs.reduce((a, b) => (...args) => a(b(...args)))
}``````

Composition function in △ Redux

We usually write call functions, but the readability is poor

``````const add1 = x => x + 1;
const mul3 = x => x * 3;
const div2 = x => x / 2;

Ordinary calling function

Then, you need to write a combination function with high readability

``````const operate = compose(div2, mul3, add1, add1);
operate(0);``````

Delta calls the compose function

`compose(div2, mul3, add1, add1)`The order and method of transmitting parameters`div2(mul3(add1(add1(0))))`The order relation of calling function

So, we wrote last time`reduceRight`Call function from inside to outside to realize the call of composite function

However, Redux uses`reduce`Called in the order of the input parameters

Let’s analyze it step by step from the perspective of EC / VO / AO stack memory scope

## 2 / step by step analysis

Let’s analyze it step by step according to: execution context, scope, scope chain, VO and AO

``````//FuncS = [div2, mul3, ADD1, ADD1] function set
//  return funcs.reduce((a, b) => (...args) => a(b(...args)))
return funcs.reduce((a, b) => {
let fn = (x) => {
return a(b(x));
};
return fn;
});``````

How to write △ analysis reduce

### (1) Compose() function call

【0】EC(C001)Suppose this is the execution context formed by the execution of compse()

Operate is a function

Then, what compose return gives is a function

``````let result = funcs.reduce((a,b)=>{
return function anonymous(x){
return a(b(x));
};
});``````

Delta result is a function

The result received by result is a function

At this time, we need to form a function private context by reducing each call to callback

In the private context of each function, an anonymous function is created

The scope of each anonymous function is different

Code execution to:`funcs.reduce(callback)`

#### ① Reduce first round traversal

【1】 First round EC (CB1)Private execution context

AO(CB1)Variable object

​ a=div2

​ b=mul3

​ anonymous=0xA001

Scope chain: < EC (CB1), EC (C001) >

Parameter assignment: a = div2; b = mul3

Variable promotion: anonymous = 0xa001

Code execution:

``````return function anonymous(x){
a(b(x));
}; //=====> 【return 0xA001】;``````

The value returned by the first cycle

#### ② Reduce first round traversal

【2】 Second round EC (CB2)Private execution context

AO(CB2)Variable object

​ a=0xA001

​ anonymous=0xA002

Scope chain: < EC (CB2), EC (C001) >

Parameter assignment: a = 0xa001; b = ADD1

Variable promotion: anonymous = 0xa002

Code execution:

``````return function anonymous(x){
a(b(x));
}; //=> 【return 0xA002】;``````

The value returned by the second cycle

#### ③ Reduce the third round traversal

【3】 The third round of EC (CB3)Private execution context

AO(CB3)Variable object

​ a=0xA002

​ anonymous=0xA003

Scope chain: < EC (CB3), EC (C001) >

Variable promotion: anonymous = 0xa003

Code execution:

``````return function anonymous(x){
a(b(x));
}; //=> 【return 0xA003】;``````

The value returned by the third cycle

### (4) After the reduce traversal, assign a value

After three rounds of traversal, the`0xA003`Assign to`operate`

`operate(0)`implement

#### ③ Execute (0xa003)

【3】EC(0xA003)

AO(0xA003)

​ x=0

Scope chain: < EC (0xa003), EC (CB3) >

Parameter assignment: x = 0

Code execution:

`a(b(x));`

= > x is its own: x = 0; both a and B are in the superior context

​ => a=0xA002

= > ADD1 (0) is regarded as the final result. In order to see the same effect at last, the calculation will not be written

= > 0xa002() call

#### ② 0xa002() call

【2】EC(0xA002)

AO(0xA002)

Scope chain: < EC (0xa002), EC (CB2) >

Parameter assignment: x = ADD1 (0)

Code execution:

`a(b(x));`

= > x is its own: x = ADD1 (0); a and B are in the superior context

​ => a=0xA001

= > 0xa001() call

#### ① 0xa001() call

【1】EC(0xA001)

AO(0xA001)

Scope chain: < EC (0xa001), EC (CB1) >

Code execution:

`a(b(x));`

= > x is its own: x = ADD1 (ADD1 (0)); a and B are in the superior context

​ => a=div2

​ => b=mul3

Namely:`div2(mul3(add1(add1(0))))`

– end –