ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

再谈JS闭包

2021-08-16 22:00:07  阅读:166  来源: 互联网

标签:闭包 function 函数 作用域 再谈 JS let 引用


闭包是外层函数作用域的引用

需求决定供给,闭包的出现是为了解决函数在定义作用域外执行时如何按照词法作用域查询变量的问题。

JS中的函数是第一公民,所以可以作为值被返回,从而在其他地方执行。当一个函数在定义作用域以外的地方执行时,如果按照正常的词法作用域,那么无法访问到定义时所在的外层函数作用域,所以闭包实际上补足了这一点。

对于一个有闭包的函数来说,访问顺序变为「本地作用域-闭包-外层作用域」,这里的闭包作为定义时外层函数作用域的引用,避免了作用域被垃圾回收,可以在任意位置进行访问。

function a() {
  let b = 1;
  function c() {
    b += 1;
    console.log(b);
  }
  return c;
}
let d = a();
debugger;
d();

image-20210816212028479

之所以一定是函数作用域,因为全局作用域最后回收,块作用域访问不到,两者不需要使用闭包来保留状态,只有函数作用域在执行完成后立刻销毁,所以需要闭包作为引用来保留状态。

疑问:当我在嵌套函数的外层添加了一个块作用域,闭包竟然没有了

function a() {
  { // 添加块
    let b = 1;
    function c() {
      b += 1;
      console.log(b);
    }
    return c;
  } // 添加块
}
let d = a();
debugger;
d();

image-20210816211841940

引用了自由变量就会创建闭包

闭包的创建取决于是否引用了外层函数作用域的变量(自由变量),和是否返回函数无关。

function a() {
  let b = 1;
  function c() {
    b += 1;
    console.log(b);
  }
  debugger;
  c();
}
a();

image-20210816213311316

引用了谁的变量就创建谁的闭包

闭包不一定是父级作用域,也可以是更外面的函数作用域,取决于引用了谁的变量。

function a() {
  let a_1 = 'a_1';
  function b() {
    function c() {
      // 这里引用了函数a的变量
      console.log(a_1);
    }
    debugger;
    c();
  }
  b();
}
a();

image-20210816213603307

引用多个作用域就创建多个闭包

如果同时引用了多个外层作用域的变量,就会创建多个闭包。

function a() {
  let a_1 = 'a_1';
  function b() {
    let b_1 = 'b_1';
    function c() {
      console.log(a_1);
      console.log(b_1);
    }
    debugger;
    c();
  }
  b();
}
a();

image-20210816214105584

总结

从上面的实验结果看,闭包实际上是嵌套函数访问词法作用域的一种特定模式,不论你是否返回内部函数,只要引用了外部函数作用域的变量,就会创建闭包,或者说内部函数是通过闭包的方式来访问外层变量。之所以会这样,还是因为函数是第一公民,存在定义和执行作用域不一致的情况,如果没有这一点,闭包也就不必存在了。

标签:闭包,function,函数,作用域,再谈,JS,let,引用
来源: https://www.cnblogs.com/Peter2014/p/15150137.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有