JavaScript基础知识--闭包(学习记录)

41 阅读2分钟

闭包又称函数闭包或者词法闭包,是在支持函数是一等公民的编程语言中出现的一种结构体,它存储了一个函数和一个关联的环境,当捕捉闭包的时候,它的自由变量会在捕捉的时候被确定,这样即使脱离了捕捉上下文,它也能照常运行。每创建一个函数,闭包就会在函数被创建出来的时候同时被创建。

/**
 * 闭包是一个函数以其捆绑的周边环境状态的引用的组合。闭包让开发者可以从内部函数访问外部函数的作用域
 * 闭包会随着函数的创建而同时被创建
 */
//来自mdn的一个例子
function makeAdder(x) {
  return function (y) {
    return x + y;
  }
}
var add5 = makeAdder(5);//这个函数的x=5变量都不会被销毁
var add10 = makeAdder(10);//这个函数x=10变量不会被销毁
//来自vue3源码工具函数
const cacheStringFunction = (fn) => {
  const cache = Object.create(null);//这里的cache就可以缓存所有函数以及函数的处理结果
  return (str) => {
    const hit = cache[str];
    return hit || (cache[str] = fn(str));
  }
}
const capitalize = cacheStringFunction((str) => {
  str.charAt(0).toUpperCase();
})
//用函数模拟私有变量
const Count = (() => {
  let a = 10;
  const changeA = (arg) => {
    a = arg;
  }
  return {
    increment: () => {
      a++;
      changeA(a);
    },
    decrement: () => {
      a--;
      changeA(a);
    },
    value: () => {
      return a;
    }
  }
})()
console.log(Count.value());
Count.increment();
Count.increment();
console.log(Count.value());

闭包会造成上层函数作用域在函数执行完毕后不释放的问题,所以大量闭包的使用会造成内存泄漏。所以当不使用闭包时,应该手动去释放内存

var n = 999;

function f1(){
  var n = 1000;
  function f2(){
    console.log(n);
  }
  return f2
}

function f3(p){
  var n = 1001;
  p();
}

f3(f1());
/**
 * 首先分析f1的执行
 * f1执行时会返回f2,在f2中访问了n,所以n也会被返回出来,里边通过var定义了一个n则不会访问var n=999;
 * 执行f3,此时执行p,但是闭包是在函数定义时生成的所以n不会是1001;而是1000
 */