python 闭包 题目_记一道闭包题目

题目

今天遇到一道经典的闭包内存泄漏问题,一下还是很难说的很清楚,这里重新理一下闭包的逻辑。var t = null;

var replaceThing = function() {

var o = t

var unused = function() {

if (o)

console.log("hi")

}

t = {

longStr: new Array(1000000).join('*'),

someMethod: function() {

console.log(1)

}

}

}

setInterval(replaceThing, 1000)

闭包分析

闭包大家都知道,重点从两个方面来理解:函数嵌套函数,内层函数引用了外层函数作用域下的变量,并且内层函数被全局环境下的变量引用,就形成了闭包。

函数内部定义的所有函数共享同一个闭包对象。

所以,看到一个函数先确定其中的函数嵌套关系,再看是否内层函数引用了外层函数作用域下的变量,这道题目中,内层函数unused引用了外层函数replaceThing作用域中的变量o, 这里就有了一个闭包对象,假如没有后面的t对象,由于函数unused并没有被全局变量引用,这个闭包对象在函数执行完后就销毁了。

但是我们看后面的代码,someMethod函数组成一个大对象被赋值给了全局变量t,这里就符合了定义“内层函数被全局环境下的变量引用”,但是很多人有疑问我这个方法里没有引用外层函数的变量啊,这里就正好符合了第二条定义“函数内部定义的所有函数共享同一个闭包对象”,因此someMethod函数跟unused共享了同一个闭包对象,隐式持有了变量o的引用,形成了一个 t -> someMethod -> o ->上一次t -> ... 的循环引用, 造成了内存泄漏。

解决方法

切断这个循环引用也就是说切断o到上一次t的引用,即在函数知性最后加上o = null即可。

问题参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值