书中有悟:一文讲清楚闭包和作用域之间的关系!

前言

闭包(closure)对于大家来说应该已经不陌生了,但是当有人问你时,你真的能讲清楚什么是闭包吗?今天这篇文章通过结合红宝书黄宝书中对闭包的定义,来讲一下闭包词法作用域之间的关系及什么是真正意义上的闭包。

关键词: 闭包、词法作用域。

如何查看闭包

首先我们创建一个html文件在浏览器打开,运行一段生成闭包的js代码。

js 复制代码
function fn() {
  var name = 'lgh'
  function fn2() {
    console.log(name)
  }
  fn2()
}
fn()

这里以谷歌浏览器为例:F12打开控制台 > 点击Source标签 > Scope > closure。具体操作可看下图示例:

上图在第14行运行时可生成闭包,所以在此处打了个断点,运行到此处就会停下来,在右侧的Scope下的closure属性出可看到在执行fn2时,生成了一个涵盖fn函数作用域的闭包,闭包下包含对外层函数变量name的引用。

闭包的定义

下面是在这两本书中关于闭包的定义。

1.javascript高级程序设计: 闭包指的是那些引用了另一个函数作用域中变量的函数,通常是在嵌套中实现的。

2.你不知道的JavaScript: 当函数可以记住并访问所在词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。

从第二个定义来看 ,其实是不认同上面的例子是闭包的。更准确来说fn2函数对a的引用方法是词法作用域的查找规则,简单来说就是fn2函数是在fn函数的词法作用域中定义并执行了,并不是真正意义上的闭包,而只是闭包的一部分!而真正意义上的闭包应该在自己定义的词法作用域外执行。即以下这段代码才是真正的闭包:

js 复制代码
function fn() {
  var name = 'lgh'
  function fn2() {
    console.log(name)
  }
  return fn2;
}
const fn3 = fn()
fn3() // 输出:lgh

fn函数通过return返回fn2,并在fn函数的词法作用域外执行,并且访问到了fn函数内的变量name,这才应该是闭包的效果;而不是引用单纯的词法作用域查找就能访问的变量

这里也有一个容易理解的误区是只有函数内部返回一个引用了其内部作用域变量的函数才算是闭包。

参考以下例子其实也是闭包:

js 复制代码
// 函数传递
function fn2(cb) {
  cb() // 输出lgh。这也是闭包,在fn的词法作用域外执行了fn3
 }

 function fn() {
  var name = 'lgh'
  function fn3() {
    console.log(name)
  }
  fn2(fn3)
 }

 fn()
js 复制代码
// 变量赋值
 var fn

 function fn2() {
  var name = 'lgh'
  function fn3() {
    console.log(name)
  }
  fn = fn3  // 内部函数赋值给外部变量
 }

 function fn4() {
  fn() // 闭包
 }

 fn2() // 执行赋值操作
 fn4() // 生成闭包

闭包生成条件

闭包是在运行时生成的。闭包 是指一个函数对象,它不仅包含了函数的代码,还记录了函数创建时的环境信息,包括函数内部的变量、参数等。这些环境信息使得闭包可以在函数定义的作用域之外被调用,并且可以访问到其定义时的变量状态。

总结

闭包可以是那些引用了另一个函数作用域中变量的函数。但真正意义上的闭包是在定义它的词法作用域外执行才能发挥它的真正的效果,也是严格意义上的闭包!

相关推荐
晴空万里藏片云41 分钟前
elment Table多级表头固定列后,合计行错位显示问题解决
前端·javascript·vue.js
曦月合一42 分钟前
html中iframe标签 隐藏滚动条
前端·html·iframe
奶球不是球44 分钟前
el-button按钮的loading状态设置
前端·javascript
kidding7231 小时前
前端VUE3的面试题
前端·typescript·compositionapi·fragment·teleport·suspense
无责任此方_修行中2 小时前
每周见闻分享:杂谈AI取代程序员
javascript·资讯
Σίσυφος19003 小时前
halcon 条形码、二维码识别、opencv识别
前端·数据库
学代码的小前端3 小时前
0基础学前端-----CSS DAY13
前端·css
dorabighead4 小时前
JavaScript 高级程序设计 读书笔记(第三章)
开发语言·javascript·ecmascript
css趣多多4 小时前
案例自定义tabBar
前端
姑苏洛言5 小时前
DeepSeek写微信转盘小程序需求文档,这不比产品经理强?
前端