当前位置: 首页 > news >正文

一道闭包题引发的思考

先看一下这个例子。

function box(){
var a=1;
return function(){
a++;
alert(a);
}
}
box()();//2
box()();//2
var c=box();
c();//2
c();//3

很久前在知乎碰到了这个问题,当时实在是不知道怎么完全解释,后来重新翻看《javascript高级程序设计》的时候才恍然大悟。

我的理解是可以用执行环境来解释。

《javascript高级程序设计》里面有这么一段话:“在js里面当执行流进入一个函数的时候,函数的环境会被推入到一个环境栈里面,函数执行结束后又会将环境弹出。”

这样前两个box()()实际上每次执行的时候,函数环境都被推入到栈里面,结束后又会被弹出,首先是box环境被推入栈中,然后里面闭包函数环境推入到栈中,执行结束后会先弹出闭包的环境,再弹出box的环境,所以两个互不影响,都是2。

但是c=box()的时候,因为c一直保持着box()的执行,所以box的执行环境一直在栈中,后面两个c()运行的时候,会推入闭包的执行环境,执行c()结束后才弹出闭包的执行环境,实际上box这个执行环境一直还在栈中,所以a就都在同一个执行环境里面了。

后来我请教了一下在百度工作的师兄,他的解释是这样的:

每个函数的作用域都是独一无二的,函数执行完后里面的东西都会清空,所以box()()执行两次后都是2。

而c,即box(),实际是一直引用着box里面的a变量,所以一直不会被清空。

这个类似于:

  var a=1;
  function c(){
   a++;
   alert(a);
  }
  c(); //2
  c(); //3

相关文章:

  • 循环 函数 软件包 【中】
  • Blue Moon响应式后台管理模板
  • 用UltraISO把硬盘文件制作成ISO格式
  • 深入理解SELinux SEAndroid
  • Android初级进阶之自定义View之SafeVeiw
  • 源码安装http2.2.29
  • Making An Indicator With Pure CSS
  • python编程中的if __name__ == 'main': 的作用和原理
  • [raspberry pi3] zram设置
  • MyEclipse Site
  • 金蝶出现问题该怎么解决
  • Access 中数据库操作时提示from子句语法错误
  • rsync服务之配置文件rsyncd.conf详细说明
  • 【223】◀▶ IDL HDF 文件操作说明
  • 角色和权限Hibernate实体映射配置
  • JS 中的深拷贝与浅拷贝
  • 「译」Node.js Streams 基础
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • js写一个简单的选项卡
  • Laravel 实践之路: 数据库迁移与数据填充
  • React-生命周期杂记
  • Redux系列x:源码分析
  • supervisor 永不挂掉的进程 安装以及使用
  • windows下如何用phpstorm同步测试服务器
  • 案例分享〡三拾众筹持续交付开发流程支撑创新业务
  • 免费小说阅读小程序
  • 排序算法之--选择排序
  • 前端面试题总结
  • 前端知识点整理(待续)
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 思否第一天
  • Linux权限管理(week1_day5)--技术流ken
  • 翻译 | The Principles of OOD 面向对象设计原则
  • 移动端高清、多屏适配方案
  • ​马来语翻译中文去哪比较好?
  • #laravel 通过手动安装依赖PHPExcel#
  • #控制台大学课堂点名问题_课堂随机点名
  • $$$$GB2312-80区位编码表$$$$
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (ZT)出版业改革:该死的死,该生的生
  • (论文阅读26/100)Weakly-supervised learning with convolutional neural networks
  • (三)uboot源码分析
  • (一)插入排序
  • (原創) 是否该学PetShop将Model和BLL分开? (.NET) (N-Tier) (PetShop) (OO)
  • .NET CORE 3.1 集成JWT鉴权和授权2
  • .Net6支持的操作系统版本(.net8已来,你还在用.netframework4.5吗)
  • .NET中两种OCR方式对比
  • @require_PUTNameError: name ‘require_PUT‘ is not defined 解决方法
  • []常用AT命令解释()
  • [2016.7 Day.4] T1 游戏 [正解:二分图 偏解:奇葩贪心+模拟?(不知如何称呼不过居然比std还快)]
  • [2023-年度总结]凡是过往,皆为序章
  • [BUG]vscode插件live server无法自动打开浏览器
  • [Codeforces] probabilities (R1600) Part.1