函数创建和执行的底层机制

120 阅读2分钟
创建一个函数
    1.开辟一个堆内存(16进制的内存地址:AAAFFF111)
    2.声明当前函数的作用域(在哪个上下文创建的,他的作用域是谁)
    3.把函数体中的代码当做“字符串”存储在堆内存中(创建一个函数,存储的是一堆字符串,所以函数如果不执行,函数其实没啥意义)
    4.把函数堆的地址类似于对象一样,放置在栈中供变量调用(函数名)
    
执行函数
    1.会形成一个全新的私有上下文EC(XXX)(目的是供函数体中的代码执行),然后进栈执行
    2.在私有上下文中有一个存放私有变量的变量对象AO(xxx)
    3.在代码执行之前要做的事情很多:
        初始化它的作用域链<自己的上下文,函数的作用域>
        初始化THIS(箭头函数没有THIS)
        初始化ARGUMENT实参集合(箭头函数没有ARGUMENTS)
        形参赋值(形参变量是函数的私有变量,存在AO中)
        变量提升(在私有上下文中声明的变量都是私有变量)
        ...
    4.代码执行(把之前的函数堆中存储的字符串,拿过来在上下文中依次执行)
        作用域链查找机制:在代码执行中,遇到一个变量,我们首先看一下是否为自己的私有变量,如果是自己的私有变量,接下来所有操作都是操作私有的(和外界没有直接的联系);如果不是自己私有的,则按照scope-chain,向上机上下文中查找(如果是上级私有的,接下来的操作都是操作上下文中的变量)...一直找,直到找到EC(G)为止
    5.根据实际的情况确定当前上下文是否出栈释放
       为了保证栈内存的大小(内存优化),一般情况下,如果当前函数执行产生的上下文,在进栈且代码执行完成后,会把上下文移除栈(上下文释放:之前在上下文存储的私有变量等信息就跟着释放了)=>全局上下文是在打开页面生成的,也需要在关闭页面的时候释放掉(只有页面关闭才会释放掉)
            特殊情况:只要当前上下文的某些内容,被上下文以外的东西占用,那么当前上下文是不能被释放的(上下文中存储的变量等信息也保留下来了)=>这种情况就是大家认为的闭包
6.函数第二次执行,会形成一个全新的私有上下文,吧之前做过的事情,还是原封不动再执行一次,两个上下文没有联系