闭包+函数+作用域

闭包是一个概念

指有权访问另一个函数作用域中的变量的函数

要理解闭包就必须要了解作用域链


函数创建 调用 执行完毕

  • 函数不过是一段可以在特定作用域执行代码的特殊对象
  • 函数是对象,所以每创建一个函数,就是实例化一个对象
  • 每创建一个函数,就会同时创建它的prototype(原型)属性指向函数原型对象
    这个对象也会自动获得constrctor属性,这个属性是指向prototype属性所在函数的指针

后台的每个执行环境都有一个表示变量的对象--变量对象。全部变量对象始终都存在

而像compare()函数这样的局部环境的变量对象,则只在函数执行的过程中存在

在创建compare()函数的时候,会创建一个预先包括全局变量对象的作用域链,这个作用域链被保存在内部的【【scope】】属性中

  • 创建函数的时候======= 预先创建一个作用域链

调用compare()函数的时候,会为函数创建一个执行环境,然后通过复制函数的【【scope】】属性中的对象构建起执行环境的作用域链。

此后,又有一个活动对象(在此作为变量对象使用)被创建并被推入执行韩晶作用域链的前端。对于这个例子中的conpare()函数的执行环境而言,

其作用域链中包含两个变量对象:本地活动对象和全局变量对象。显然,作用域链本质上是一个指向变量对象的指针列表,它只引用但不包含变量对象

  • 调用函数的时候=======创建执行环境及相应的作用域链,使用arguments和其他命名的参数的值来初始化函数的活动对象
  • 函数执行完毕后=======局部活动对象就会被销毁,内存中仅保存全局作用域

上面一直提到调用一个函数,会创建一个执行环境,那么什么是执行环境??

执行环境

概念:执行环境(环境)是js中重要的一个概念,执行环境定义了变量或函数有权访问的其他数据,决定他们的各自行为。

概念详解每个执行环境都有一个与之关联的变量对象,环境中定义的函数和变量都保存在这个对象中,我们无法访问这个对象

全局执行环境:全局执行环境是最外围的一个执行环境。web浏览器中全局执行环境被认为window。因为所有全局变量和函数都是作为window对象的属性和方法创建的。

环境执行完毕某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义随之销毁(全局环境知道应用程序推出,关闭网页和浏览器时才销毁)

执行流机制每个函数都有自己的执行环境。当执行流进入一个函数的时候,函数的环境被推入一个环境栈中。而在函数执行之后,栈将其环境弹出,把控制权返回给之前
的执行环境,

作用域链是保证对执行环境有权访问的所有变量和函数有序访问

代码执行:当代码在一个执行环境中执行时,会创建变量对象的一个作用域链。作用域链的作用:是保证对执行环境有权访问的所有变量和函数有序访问
作用域的前端,始终都是当前执行代码所在环境的变量对象。如果这个环境是函数,则将其活动对象作为变量对象。活动对象最开始的时候只包含一个变量
:arguments对象(这个对象在全局环境中是不存在的)。作用域链中的下一个变量对象来自包含(外部)环境。而再下一个变量对象来自于下一个包含环境,
这样,一直延续到全局的执行环境。标识符解析是沿着作用域一级一级向后搜索(没找到会导致报错)

var scope = "全局执行环境"

function swapScope() {
    var anotherScope = "一级局部环境"
    
    function changeScope() {
        var tempScope = anotherScope
        anotherScope = scope
        scope = tempScope
        //这里可以访问 scope anotherScope  tempScope
        }
// 这里可以访问 scope anotherScope  不能访问 tempScope   
 }    
//这里只能访问scope

//以上代码涉及三个执行环境:全局执行环境,swapScope()的局部环境
和changeScope局部环境
对于changeScope函数而言,其作用域中包含三个对象:全局变量对象,changeScope的变量对象和swapScope的变量对象。

猜你喜欢

转载自www.cnblogs.com/-constructor/p/11742407.html