资讯专栏INFORMATION COLUMN

三个闭包实例理解闭包对内存的影响

jackzou / 1917人阅读

摘要:在试图弄清这个问题之前,先要理解栈内存堆内存和预处理。因此在子函数执行的时候,堆内存被占用了,相应的栈内存也将保留。所以,栈内存在执行完之后会被保留一段时间,这段时间等于其子函数执行的时间。

在试图弄清这个问题之前,先要理解栈内存、堆内存和预处理。

占用内存,不会销毁的闭包实例 例1:
var num = 12;
function fn() {
    var num = 100;
    return function () {
        console.log(num);
    }
}
var f = fn();
f();

例1的图示

未被占用的堆内存才会被销毁

所以,正如图中椭圆形关键点中说明的那样,堆内存xxxfff111被返回给了全局变量f,而全局变量只有在窗口关闭的时候才会销毁,因此堆内存xxxfff111将一直被占用而不会销毁,定义它的局部作用域A也不会被销毁。

例2
var oDiv = document.getElementById("div1");
~function() {
    oDiv.onclick = function() {

    }
}();

这段代码的特点是:私有作用域给DOM元素的事件绑定一个方法。

例2的图示:

正如图中椭圆形关键点所说,标签对象的属性里面会自带一个onclick的属性,未被赋值时其值为null。那么,在自执行函数执行的时候,其创建的作用域所占用的堆内存xxxfff111同样也会被全局的堆内存xxxfff000占用(这里要注意,是堆内存占用堆内存),所以堆内存xxxfff111和栈内存A都不会被销毁。

不占用内存,立即销毁的实例

只需要将例1稍作修改。

例3:
function fn(){
    var num = 100;
    return function(){
        console.log(num);
    }
}
fn();    //主要修改在这里

例3的图示

由于在函数fn中,xxxfff111是被return的,所以栈内存A的预解释不会处理xxxfff111,它只在fn函数执行的时候才会生成,而函数fn的栈内存A每次被执行之后都会被销毁。

暂时占用内存,延时销毁的闭包实例

将例3稍作修改,就变成了延时销毁的闭包实例。

例4:
function fn(){
  var num = 100;
  return function(){

  }
}
fn()();    //这里到底发生了什么?其实是执行了一次fn之后,把返回的子函数有执行了一次,所以在子函数执行的时候,栈内存fn()是不能销毁的,但是子函数执行完毕后因为没有被占用,所以最终fn()还是会被销毁的。

例4的图示:

正如图中椭圆形关键点处所说,fn()()的意思是在执行完fn()之后再把返回的值函数执行一遍。因此在子函数执行的时候,堆内存xxxfff111被占用了,相应的栈内存A也将保留。

可堆内存xxxfff111中保存的子函数在执行完成之后还是会被销毁,接着堆内存xxxfff111就作为未被占用的堆内存而被销毁,最终栈内存A也会被销毁。

所以,栈内存在执行完之后会被保留一段时间,这段时间等于其子函数执行的时间。

参考资料:

JavaScript高级程序设计(第三版)。

我在github
https://github.com/zhuanyongx...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/107411.html

相关文章

  • JS中对内存的一些了解

    摘要:中对内存的一些了解在进行开发的过程中了解内存机制有助于开发人员能够清晰的认识到自己写的代码在执行的过程中发生过什么也能够提高项目的代码质量内存是怎么样的中变量存放有着原始值与引用值之分原始值原始的数据类型以及新加入的引用值等类型的值便是引用 JS中对内存的一些了解 在JS进行开发的过程中, 了解JS内存机制有助于开发人员能够清晰的认识到自己写的代码在执行的过程中发生过什么, 也能够提高...

    elliott_hu 评论0 收藏0
  • 深入理解JavaScript(二):由一道题来思考闭包

    摘要:中所有的事件绑定都是异步编程当前这件事件没有彻底完成,不再等待,继续执行下面的任务当绑定事件后,不需要等待执行,继续执行下一个循环任务,所以当我们点击执行方法的时候,循环早已结束即是最后。 概念 闭包就是指有权访问另一个函数作用域中的变量的函数 点击li标签弹出对应数字 0 1...

    曹金海 评论0 收藏0
  • 一年内经验前端面试题记录

    摘要:对于,其默认大小一般是本地存储和都保存在浏览器端,且都是同源的。把变量放在闭包中和放在全局作用域,对内存的影响是一致的,这里并不能说成是内存泄露。将新的树和之前的虚拟树进行相比较,根据结果对进行精准响应。 1. JavaScript 1. JavaScript文件在什么情况下会放在html哪个位置 https://zhuanlan.zhihu.com/p/... 对于必须要在DOM加载...

    qianfeng 评论0 收藏0
  • 一年内经验前端面试题记录

    摘要:对于,其默认大小一般是本地存储和都保存在浏览器端,且都是同源的。把变量放在闭包中和放在全局作用域,对内存的影响是一致的,这里并不能说成是内存泄露。将新的树和之前的虚拟树进行相比较,根据结果对进行精准响应。 1. JavaScript 1. JavaScript文件在什么情况下会放在html哪个位置 https://zhuanlan.zhihu.com/p/... 对于必须要在DOM加载...

    kelvinlee 评论0 收藏0

发表评论

0条评论

jackzou

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<