-
我在 Python 的循环里批量造了一串函数,每个本该记住自己那一轮的编号,结果调用时它们却异口同声地全返回了最后一个数,排查半天发现闭包记住的是变量本身、而不是当时那个值的深度复盘
我有个需求:根据一个列表批量生成一串回调函数,每个被调用时应返回它对应的索引——第 0 个返回 0、第 1 个返回 1。我很自然地在 for 循环里用 lambda 一个个造出来,自觉天衣无缝。可一调用就傻眼:这串函数无论调哪一个,返回的全是同一个数——最后一个索引!它们仿佛集体失忆,谁也没记住自己出生那一刻的编号,而是异口同声报出同一个数。我盯着那段再正常不过的循环百思不得其解:明明每轮 i 都…- 0
- 0
-
我在一个循环里处理几千个文件、每个都顺手 defer 关闭,结果跑到一半报 too many open files,因为那些 defer 全攒到函数返回才执行:一次 Go defer 在循环里堆积的深度复盘
我有个函数要在 for 循环里依次处理几千个文件,每打开一个就顺手 defer file.Close() 确保关闭——这是 Go 管理资源的标准姿势。可线上跑到几百上千个文件时就报 too many open files 崩了。查清 defer 的执行时机才明白:defer 注册的函数是在当前函数返回时才执行,而不是当前循环迭代结束时;我在循环里 defer,这几千个 Close 并没有在每次迭代…- 0
- 0
-
我把一个对象的方法直接当回调传给了 setTimeout 和事件监听,触发时报 Cannot read properties of undefined:一次 JavaScript this 指向丢失、把方法拆离对象就丢了绑定的深度复盘
我写了个 class 管理面板,把方法 handleClick 直接当回调传给按钮的 addEventListener,点击时控制台爆红:Cannot read properties of undefined (reading 'state')。同样的事发生在 setTimeout(panel.refresh, 1000) 上。这方法明明是 panel 的,this 怎么会是 …- 0
- 0
-
一个把对象方法直接作为回调传给 setTimeout 的写法,执行时 this 变成了 undefined、访问 this 的属性全报错:一次 JavaScript this 绑定丢失的深度复盘
把对象的方法 handleClick(里面用了 this.count)作为回调传给 setTimeout,执行时报 Cannot read properties of undefined——this 居然是 undefined。根因是 JS 的 this 不由'函数在哪定义'决定、而由'如何被调用'决定:setTimeout(obj.fn) 只是把函数本身取…- 0
- 0
-
我在循环里批量创建了一组函数,本想让它们各自记住循环时的值,结果调用时它们全都返回了循环结束后那个最终值,我对着 Python 闭包捕获的是变量而非值这个延迟绑定的坑排查大半天的复盘
一个让我对 Python 闭包到底记住了什么彻底搞明白的坑,诡异在我分明在循环里给每个函数都用了当时的循环值,可这些函数全都失忆了——记住的不是各自创建时的值而是所有函数共享的循环结束后同一个最终值。要在循环里批量创建一组函数,每个应记住对应的循环值:for i in range(3): funcs.append(lambda: i)。期望调用得到 [0,1,2],实际却是 [2,2,2] 全是 …- 2
- 0
-
我在 for 循环里处理一批文件、每个都 defer f.Close(),结果跑到一半就报 too many open files,我对着 defer 的执行时机排查了大半天的复盘
写了个 Go 批处理:一个函数里 for 循环遍历几千个文件,每个打开、处理、defer f.Close() 关闭,自觉很规范每个打开都配了 defer Close。结果跑到一半就崩:too many open files。困惑——我明明每个文件都 defer Close 了啊怎么还打开太多?排查大半天才理解 defer 一个关键却极易忽略的特性:defer 是在"函数返回时"…- 0
- 0
-
我在 Go 的循环里用 defer 关闭打开的文件,自以为每轮都妥妥地释放了,结果批量处理几千个文件时却报了 too many open files,我排查了大半天的复盘
我批量处理文件,在循环里逐个 os.Open 后 defer f.Close(),自以为每轮就关、很安心,少量文件也确实没事。可处理几千个文件时程序跑到一半崩了,报 too many open files。我每个都 defer Close 了啊,怎么会打开过多?深挖才懂我搞错了 defer 的执行时机:defer 是"函数级"延迟,在所在函数即将 return 时才执行,不是循…- 0
- 0
-
我把对象的方法当回调传给了 setTimeout,结果一执行就报 this 是 undefined、方法里的属性全访问不到,我对着这个丢了 this 的方法排查了大半天的复盘
我的方法在 obj 上直接调用一切正常,可一把它当回调传给 setTimeout(或事件监听、forEach),回调一执行就报 Cannot read properties of undefined——打印 this 竟是 undefined,方法里 this.xxx 全访问不到。同一个方法,直接调好好的,怎么一传出去 this 就丢了?深挖才懂:JavaScript 的 this 不是定义时绑定…- 0
- 0
-
我在 Python 的循环里批量创建了一串函数,本以为每个都记着各自的循环值,结果调用时它们竟然全都返回了同一个最后的值,我排查了大半天的复盘
我在 Python 循环里用 lambda 批量创建了一串函数装进列表,本以为它们会分别返回 0、1、2,结果挨个调用竟全返回 2——循环的末值,每个函数都"失忆"了。深挖才懂:Python 闭包是"延迟绑定(late binding)"——lambda 捕获的不是"创建时 i 的值",而是"变量 i 本身"的引用,它…- 0
- 0
-
我在循环里用 var 注册了几个回调,本想让它们各自打印 0、1、2,结果它们齐刷刷全打印了 3,我盯着这个诡异的结果排查了大半天的深度复盘
我在 for 循环里用 var 注册了几个 setTimeout 回调,本想让它们各自打印 0、1、2,结果它们齐刷刷全打印了 3。这几个回调明明在 i 不同时刻创建,怎么全记住了循环结束后的 3?深究才懂是两个机制叠加:一,var 是函数作用域不是块作用域,整个循环只有一个共享的 i;二,闭包捕获的是变量(引用)而非那一刻的值。加上回调是异步延迟执行的——执行时循环早跑完、共享的 i 已是 3,…- 2
- 0
-
给五个按钮绑点击事件,点哪个都弹出"第 5 个":我在 JavaScript 里被一个 for 循环里的 var 闭包坑到怀疑人生,以及作用域与闭包的全面复盘
动态生成五个按钮,点第几个就弹"第几个"——结果点哪个都弹"第 5 个"。绑定时打印 i 明明是 0~4,执行时却全变 5。根因是 var 函数作用域:整个循环只有一个 i,而五个闭包捕获的是这个变量的引用而非值。这篇复盘讲清原理、let 一字之差的正解、IIFE 等老办法,并延伸到 setTimeout 异步亲戚坑,以及闭包既是坑也是 JavaScript…- 0
- 0
-
同一个方法自己调好好的、一传给 setTimeout 或事件监听当回调就报 this 是 undefined:JavaScript this 绑定丢失的避坑复盘
这是一个让我对 JavaScript 的 this 彻底改观的 bug,也是几乎每个 JS 开发者都会踩一次的成人礼。事情是这样的:我写了一个类里面有个方法 handleClick,方法里要用到这个类实例的一些数据比如 this.state。开发时我直接调用 instance.handleClick 一切正常,可当我把这个方法作为回调函数传出去,比如绑给一个按钮的点击事件或者塞进一个 setTim…- 0
- 0
-
所有按钮都触发最后一项:JS 闭包与 var 陷阱
一个再简单不过的需求:页面动态渲染一排按钮,每个对应一条数据,点击弹出你选了第几项。我三下五除二写完,本地点第一个按钮弹出的却是最后一项,点第二个还是最后一项,点哪个通通是最后一项,功能演示当场翻车,而我盯着那段自认为毫无问题的代码百思不得其解。把循环变量打印出来才看清真相:每个按钮的点击回调里拿到的 i 全都是循环结束后的最终值,罪魁祸首是那个我用了无数次从没多想的关键字 var——它声明的 i…- 4
- 0
-
彻底搞懂 JavaScript 闭包:从作用域链到内存泄漏的完全指南
先看一段几乎每个 JavaScript 面试都会出现的代码,如果你能一眼说清它的输出,以及为什么,那这篇文章对你而言是复习;如果你还会犹豫,那它会帮你把"闭包"这件事彻底钉死在脑子里。 for (var i = 0; i < 3; i++) { setTimeout(function () { console.log(i); }, 0); } // 输出:3 3 3 ——…- 0
- 0
作用域
幸运之星正在降临...
点击领取今天的签到奖励!
恭喜!您今天获得了{{mission.data.mission.credit}}积分
我的优惠劵
-
¥优惠劵使用时效:无法使用使用时效:
之前
使用时效:永久有效优惠劵ID:×
没有优惠劵可用!














