闭包



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

    函数a返回函数b时,如果函数b引用了函数a的局部变量,实际的返回值就变成了函数b的函数体一个闭包,闭包里是函数b用到的全部变量

    创建函数:

    • 创建作用域链
    • 将作用域链保存在函数内部属性[[scope]]

    调用函数

    • 创建执行环境
    • 复制[[scope]]属性中的作用域链

    补充:变量对象与活动对象

    • 变量对象
      • 变量对象就是执行环境中包含了所有变量函数的对象
      • 变量对象是后台的,保存在内存中的,代码无法直接访问的。
    • 活动对象
      • 函数调用了,函数中才会有活动对象,否则只有“处于静止状态”的变量对象,当然也没有创建执行环境。
      • 活动对象就是作用域链上正在被执行和引用的变量对象

    function closure(propertyName) {
      return function(obj) {			//定义并返回一个闭包
        return obj[propertyName];
      };
    };
    
    let person = {name: "Shaw", age: 19};
    let sayName = closure("name");
    let sayAge = closure("age");
    console.log(sayName(person), sayAge(person))
    

    第二行在closure函数执行完毕以后,它的活动对象propertyName有没有被销毁,因为匿名函数的作用域链仍然在引用这个活动对象;即外部函数返回后,其执行环境的作用域链会被销毁,但活动对象仍存在于内存中;直到匿名函数被销毁后,外部函数的活动对象才会被销毁。

    function createFunctions() {
      var result = new Array();
      for(var i = 0; i < 10; i++) {
        result[i] = function() {
          return i;
        }
      }
      return result;
    }
    for(let i = 0; i < 10; i++) {
      console.log(createFunctions()[i]());
    }
    

    在声明函数createFunctions()时,给每个result[i]分配了一个函数定义,这个函数是一个匿名函数

    在倒数第二行对每个result[i]执行这个匿名函数时,return i时会在这个匿名函数的作用域链中查找变量i的值,由于在定义函数时,i的值已经循环到了10,则返回值均为10


 

Copyright © 2018 bbs.dian.org.cn All rights reserved.

与 Dian 的连接断开,我们正在尝试重连,请耐心等待