前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >javascript必须要知道的闭包,怎么调试闭包

javascript必须要知道的闭包,怎么调试闭包

作者头像
开水泡饭
发布2022-12-26 16:26:21
4710
发布2022-12-26 16:26:21
举报

闭包

闭包(closure)是一个函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合。换而言之,闭包让开发者可以从内部函数访问外部函数的作用域。在 JavaScript 中,闭包会随着函数的创建而被同时创建。

  • 闭包:函数和其周围状态(词法环境)的引用捆绑在一起形成闭包
    • 可以在另一个作用域中调用一个函数的内部函数并访问到该函数作用域中的成员
  • 闭包的本质: 函数在执行的时候会放到一个执行栈上当函数执行完毕后会从执行栈上移除,但是堆上的作用域成员因为被外部引用不能被释放,因此内部函数依然可以访问外部函数的成员

看下面这个代码的执行过程, 当我们调用 makeFunc1 的时候他里面会创建一个 名为 name 的变量, 当函数执行完毕的时候,函数内部的成员会被释放掉。如果这个函数里面又返回了一个函数,并且在返回的这个函数里又访问了外部函数的成员,其实这就是闭包。makeFunc2 其实就产生了闭包,当调用完 makeFunc2 的时候它会返回一个函数, myFunc 其实就引用了makeFunc2中返回的函数,当外部对内部有引用的时候makeFunc2 内部的成员就不会被释放, myFunc 依然可以访问 makeFunc2 中名为 name 的变量

代码语言:javascript
复制
function makeFunc1() {
  var name = "hellow closure";
}

makeFunc1()

function makeFunc2() {
  var name = "hellow closure";
  function displayName() {
      alert(name);
  }
  return displayName;
}

var myFunc = makeFunc2();
myFunc();

例子

在做项目中可能会出现多次求2次方或者3次方或者n次方的情况,Math.pow 可以求但是我们并不想重复的传入n次方的参数,所以我们把n次方函数抽离出来

代码语言:javascript
复制
Math.pow(4, 2)
Math.pow(5, 2)

function makePower(power) {
  // 返回了一个函数
  return function (number) {
    // 访问了外部函数的成员 power 
    return Math.pow(number, power)
  }
} 

// 求平方
let power2 = makePower(2)
let power3 = makePower(3)

console.log(power2(2))
console.log(power3(2))
console.log(power2(4))
console.log(power3(4))

调试闭包的方法

  • 浏览器打开我们需要调试的页面,打开开发者工具调到 sources 下找到我们需要调试的文件,在第一次调用的地方打上断点,刷新一下浏览器
image-20221017232204873
image-20221017232204873
  • 当第一次执行到断点的时候观察开发者工具右边的位置
    • call stack 函数调用栈: 现在我们代码在script 标签里面,script标签里面的代码都是在一个匿名函数中调用的
    • scope 作用域:全局作用域就是我们的window对象
image-20221017232438071
image-20221017232438071
  • 继续往下执行按f11跳进函数内部
    • call stack 函数调用栈:我们继续看 call stack 这个位置, 此时栈顶是makePower
    • scope 作用域:此时出现了一个local 也就是局部作用域,此时 makePower 的参数 power的值是 2
image-20221017232940042
image-20221017232940042
  • 继续往下执行,此时makePower已经执行完了,在看call stack makePower 已经被移除了,我们开始说过函数执行完了会从执行栈上移除,同时作用域scope也被移除,看不到了,此时多了一个Script 里面有一个power2,这个power2是我们用let 定义的 power2变量。let 定义的会挂载到Script上, 通过 var 定义的变量会在全局属性上
image-20221017233520436
image-20221017233520436
  • 接下来我们调试求平方的函数,在进入函数中的时候我们发现产生了新的局部作用域,此时下面多了一个Closure,这个就是闭包相关的变量,里面有个power 他的值依然在内存中存在,通过控制台调试我们可以清楚地看到闭包发生的位置
image-20221017234201121
image-20221017234201121
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 闭包
    • 例子
      • 调试闭包的方法
      相关产品与服务
      云开发 CLI 工具
      云开发 CLI 工具(Cloudbase CLI Devtools,CCLID)是云开发官方指定的 CLI 工具,可以帮助开发者快速构建 Serverless 应用。CLI 工具提供能力包括文件储存的管理、云函数的部署、模板项目的创建、HTTP Service、静态网站托管等,您可以专注于编码,无需在平台中切换各类配置。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档