闭包的概念

闭包指的是那些引用了另一个函数作用域中变量的函数,通常是在嵌套函数中实现的。

红宝书(p178)上对于闭包的定义:闭包是指有权访问另外一个函数作用域中的变量的函数。

MDN 对闭包的定义为:闭包是指那些能够访问自由变量的函数。 其中自由变量,指在函数中使用的,但既不是函数参数arguments也不是函数的局部变量的变量,其实就是另外一个函数作用域中的变量。

  1. function getOuter(){
  2. var date = '1127';
  3. function getDate(str){
  4. console.log(str + date); //访问外部的date
  5. }
  6. return getDate('今天是:'); //"今天是:1127"
  7. }
  8. getOuter();

其中date既不是参数arguments,也不是局部变量,所以date是自由变量。

总结起来就是下面两点:

  • 1、是一个函数(比如,内部函数从父函数中返回)
  • 2、能访问上级函数作用域中的变量(哪怕上级函数上下文已经销毁)

    内部变量

函数内部的变量,在函数外部是无法获取并且修改的。

  1. function f() {
  2. var n = 1
  3. n = n + 1 // 我们打算让每执行一次,n+1
  4. return n
  5. }
  6. f() // 2
  7. f() // 2
  8. f() // 2
  9. // 每次执行函数,变量都被重新设置,并没有实现我们要的效果

闭包

闭包就是在函数的内部,在构建一个子函数,去影响函数的值,从而达到修改函数内部变量的效果。

  1. function f() {
  2. var n = 0
  3. return (function() {
  4. console.log(n++) // 子函数,每次修改父函数的 n + 1,并且通过父函数返回到外部
  5. })
  6. }
  7. add = f()
  8. add() // 0
  9. add() // 1
  10. add() // 2

对于闭包有下面三个特性:

  • 1、闭包可以访问当前函数以外的变量
  1. function getOuter(){
  2. var date = '815';
  3. function getDate(str){
  4. console.log(str + date); //访问外部的date
  5. }
  6. return getDate('今天是:'); //"今天是:815"
  7. }
  8. getOuter();
  • 2、即使外部函数已经返回,闭包仍能访问外部函数定义的变量
  1. function getOuter(){
  2. var date = '815';
  3. function getDate(str){
  4. console.log(str + date); //访问外部的date
  5. }
  6. return getDate; //外部函数返回
  7. }
  8. var today = getOuter();
  9. today('今天是:'); //"今天是:815"
  10. today('明天不是:'); //"明天不是:815"
  • 3、闭包可以更新外部变量的值
  1. function updateCount(){
  2. var count = 0;
  3. function getCount(val){
  4. count = val;
  5. console.log(count);
  6. }
  7. return getCount; //外部函数返回
  8. }
  9. var count = updateCount();
  10. count(815); //815
  11. count(816); //816