JS基本知识

JS作用域的内存模型

每个函数都有各自的作用域、作用域链、变量对象、执行环境。 
一、函数初始化:3作用域链。

  • 函数被调用:1作用域、2变量对象、4执行环境。
  • 执行结束后,1作用域、3作用域链、4执行环境被销毁、2变量对象(如果函数内部有闭包变量对象仍然留在内存)。
  • 等到闭包执行结束,该变量对象将被销毁。

1.作用域

函数:当前执行的函数能够访问到变量的范围

变量:变量可以活动的范围

2.变量对象

每个函数都会创建各自的变量对象。

作用域:存储的变量对象的引用;

变量对象:存储函数局部变量。

3.作用域链

把多个作用域串起来便形成了作用域链;

函数初始化:生成作用域链(不包含自己的作用域);

函数被调用:创建自己的作用域,并加入到作用域链的开头;

作用域链中不仅存储了函数本身的作用域,还存储了该函数能够访问的其他函数的作用域。

4.执行环境

所有的执行环境会存放在执行环境栈(执行环境栈顶表示当前正在执行的环境)中,只有栈顶的执行环境才有执行权。

每个正在执行的函数都有一个执行环境,记录了函数执行过程中的各项信息。 
除了全局执行环境外,其余函数的执行环境都随着函数的执行而被创建,随着函数的执行结束而被销毁。 

var 全局变量 = "柴毛毛";

function 外层函数(){

    var 局部变量1 = "大闲人";

    return function(){

        var 局部变量2 = "是傻逼";

        return 全局变量+局部变量1+局部变量2;

    };

}

var 函数 = 外层函数();

函数();

  • 初始化全局执行环境
  1. 创建全局变量对象。
  2. 创建全局作用域链。该作用域链中只包含一个全局变量对象作用域链中通过指针指向全局变量对象。
  3. 创建外层函数的作用域链。只包含外层函数父级函数的作用域链。
  4. 创建全局执行环境。将全局执行环境压入执行环境栈,并通过一个指针指向它的作用域链。 

  • 调用外层函数
  1. 创建外层函数的变量对象“局部变量1”和匿名函数
  2. 将当前函数的作用域添加到当前函数作用域链的顶部。也就是把先前创建的“外部函数作用域链”中第一个作用域的指针指向“外部函数变量对象”,第二个指针指向“全局变量对象”。
  3. 创建外层函数中匿名函数的作用域链即图中的闭包作用域链。
  4. 将“外层函数的执行环境”压入执行环境栈的顶部。并指向外层函数的作用域链。

  • 调用闭包(即匿名函数)
  1. 销毁“外层函数”的作用域链和执行环境。但不销毁闭包需要用到的外层函数的变量对象。
  2. 创建闭包的变量对象。
  3. 创建闭包的作用域,并压入闭包作用域链的头部。
  4. 将“闭包的执行环境”压入执行环境栈的顶部。并指向闭包的作用域链。
  5.  只有当闭包执行结束后,“外层函数的变量对象”才会被释放,否则它将一直驻留内存,这也就是为什么闭包会比普通函数占用更多的内存。

补充:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值