闭包

一个函数嵌套另一个函数并返回,通过另一个函数访问这个函数的局部变量,解决外部函数不能访问局部变量的问题

应用:1、for循环中的经典应用;2、防抖节流

闭包要解决什么问题?

  1. 闭包内的数据不允许外界访问
  2. 要解决的问题就是间接访问该数据

函数就可以构成闭包, 要解决的问题就是访问到函数内部的数据

我们观察下面的函数foo,在foo内部有一个变量num,能否在函数外部访问到这个变量num呢?

function foo () {
  var num = 123;
  return num;
}
var res = foo();
console.log( res ); // => 123

分析:

在上面的代码中,确实可以访问到num这个函数内部的变量。但是能不能多次访问呢?

不能,因为每次访问都得重新调用一次foo函数,每次调用都会重新创建一个num = 123,然后返回。

解决思路

函数内的数据不能直接在函数外被访问,是因为作用域的关系,上级作用域不能直接访问下级作用域中的数据。

但是如果反过来,下级作用域可以直接访问上级作用域中的数据。那么如果在函数foo内定义一个函数,那么在这个内部函数中是可以直接访问foo中的num的。

function foo() {
  var num = Math.random();    
  function func() {
    return num;    
  }
  return func;
}
var f = foo();
// f可以直接访问num,而且多次访问,访问的也是同一个,并不会返回新的num
var res1 = f();
var res2 = f();

如何获得超过一个数据

函数的返回值只能有一个,那按照上面的方法,我们只能对函数内部的一个数据进行操作。怎么操作函数内的多个数据呢?

可以使用对象,代码如下:

function foo () {
  var num1 = Math.random();
  var num2 = Math.random();

  //可以将多个函数包含在一个对象内进行返回,这样就能在函数外部操作当前函数内的多个变量
  return{
    num1: function () {
      return num1;
    },
    num2: function () {
      return num2;
    }
  }
}

如何完成读取一个数据和修改这个数据

前面讲的都是如何去获取函数内部的数据,接下来我们考虑如何修改函数内部的数据。

同样,也是使用内部的函数进行操作。

function foo() {
  var num = Math.random();
  //分别定义get和set函数,使用对象进行返回
  return {
    //get_num负责获取数据
    get_num: function() {    
      return num;
    },
    //set_num负责设置数据
    set_num: function(value) {
      num = value;
    }
  }
}

闭包的基本结构

一般闭包要解决的问题就是要想办法间接的获得函数内数据的使用权. 那么我们的可以总结出一个基本的使用模型

  1. 写一个函数, 函数内定义一个新函数, 返回新函数, 用新函数获得函数内的数据
  2. 写一个函数, 函数内定义一个对象, 对象中绑定多个函数( 方法 ), 返回对象, 利用对象的方法访问函数内的数据

results matching ""

    No results matching ""