闭包,闭包的本质

42 阅读2分钟
  1. 概念

闭包函数: 声明在一个函数中的函数,叫做闭包函数。

闭包: 内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回了之后。

  1. 闭包的应用场景
  • 创建独立的模块,封装私有变量和方法,避免全局污染
  • 回调函数
  • 高阶函数,如防抖和节流
  • 函数工厂,动态生成函数

。。。。。。

  1. 闭包的创建

闭包就是可以创建一个独立的环境,每个闭包里面的环境都是独立的,互不干扰。闭包会发生内存泄漏,每次外部函数执行的时候,都会开辟一块内存空间,外部函数的引用地址不同,都会重新创建一个新的地址

结论: 闭包找到的是同一地址中父级函数中对应变量最终的值

例子一:

function outerFn(){
  var i = 0; 
  function innerFn(){
      i++;
      console.log(i);
  }
  return innerFn;
}
var inner = outerFn();  //每次外部函数执行的时候,都会开辟一块内存空间,外部函数的地址不同,都会重新创建一个新的地址
inner();
inner();
inner();
var inner2 = outerFn();
inner2();
inner2();
inner2();   //1 2 3 1 2 3

例子二:

for (var i = 0; i < 10; i++) {
    const task = () => new Promise(resolve => {
    // 这里 i 的值是以前非常高频的闭包题
        setTimeout(() => {
            console.log(`task${i} complete`);
            resolve(`task${i}`);
        }, 2000);
    });
    task();
}
// 输出
task10 complete
task10 complete
task10 complete
task10 complete
task10 complete
task10 complete
task10 complete
task10 complete
task10 complete
task10 complete

例子三:

for (let i = 0; i < 10; i++) {
    const task = () => new Promise(resolve => {
        // 这里 i 的值是以前非常高频的闭包题
        setTimeout(() => {
            console.log(`task${i} complete`);
            resolve(`task${i}`);
        }, 2000);
    });
    task();
}
// 输出
task0 complete
task1 complete
task2 complete
task3 complete
task4 complete
task5 complete
task6 complete
task7 complete
task8 complete
task9 complete

例子四:

for (var i = 0; i < 10; i++) {
    (function(i) { // 立即执行函数创建独立作用域
        const task = () => new Promise(resolve => {
            setTimeout(() => {
                console.log(`task${i} complete`); // 捕获 IIFE 内部的 i
                resolve(`task${i}`);
            }, 2000);
        });
        task();
    })(i); // 传入当前迭代的 i 值
}

例子五:

function outerFn(){
  var i = 0; 
  function innerFn(){
      i++;
      console.log(i);
  }
  return innerFn;
}
var inner = outerFn();  //每次外部函数执行的时候,都会开辟一块内存空间,外部函数的地址不同,都会重新创建一个新的地址
inner();
inner();
inner();
var inner2 = outerFn();
inner2();
inner2();
inner2();   //1 2 3 1 2 3
var  fn=(function(){
   var  i=10;
   function  fn(){
      console.log(++i);
   }
   return   fn;
})() 
fn();   //11
fn();   //12

一些碎碎念~