IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 闭包是什么?闭包造成的内存泄漏又怎么解决? -> 正文阅读

[游戏开发]闭包是什么?闭包造成的内存泄漏又怎么解决?

本文围绕三个二级目录展开描述闭包与内存泄漏,请看下文:

闭包是什么?

一.维基百科对闭包的定义:

  1. 闭包又称此法闭包或函数闭包;
  2. 是在支持头等函数的编程语言中,实现词法绑定的一种技术;
  3. 闭包在是实现上是一个结构体,它存储了一个函数和一个关联的环境;
  4. 闭包跟函数的最大区别在于,当捕捉闭包的时候,它的自由变量会在捕捉时被确定,这样及时脱离了捕捉时的上下文,它也能照常运行;

二.MDN对JavaScript闭包的解释:

  1. 一个函数和对其周围状态的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包。
  2. 也就是说,闭包让你可以在一个内层函数中访问到期外层函数的作用域。
  3. 在JavaScript中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。

相信大家看了上面的官方解释并不怎么理解闭包是什么?自由变量又是什么?接下来使用一个小demo进行解释:

function foo () {
    var name = 'foo'
    function bar () {
        console.log('bar', name)
    }
    return bar
}
var fn = foo()
fn() // bar foo

上述示例代码中, bar 函数本身与自由变量name组成了严格意义上的闭包。
一个函数和对其周围状态的引用捆绑在一起(或者说函数被引用包围)对于这句话的理解,此时的一个函数指的就是bar函数,自由变量name就是捆绑在一起的。二者组合就是闭包。

闭包一定会在函数创建的同时被创建出来吗?

在JavaScript中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。
这句话我们是怎么理解的呢?如果不访问自由变量也是闭包吗?
接下来继续展示一个小demo进行分析,示例代码如下:

// can函数
var can = 'can'
function can () {
    console.log(can)
}
// not函数
function not () {

}

/* 
	两个不同的函数一个访问了自由变量,一个没有访问自由变量,两个谁是闭包谁又不是闭包呢?
	首先,can函数访问了自由变量can,所以他们两个组合称为闭包;
	其次,not函数有两种不同的理解:
		1. 可以访问自由变量(但这里没有访问)也可称为闭包
		2. 没有访问自由变量,称不上闭包      
*/

个人小结:
一个普通的函数function,如果它可以访问外层作用域的自由变量,那么这个函数就是一个闭包;
从广义上的角度来说,JavaScript中的函数都是闭包;
从狭义的角度来说,JavaScript中一个函数,如果访问了外层作用域的变量,那么它是一个闭包。


闭包造成的内存泄漏怎么解决呢?

内存泄露是指:用动态存储分配函数内存空间,在使用完毕后未释放,导致一直占据该内存单元。直到程序结束。指任何对象在你不再拥有或需要它之后仍然存在。
还是写一个小demo来进行分析,示例代码如下:

function foo () {
    var name = 'foo'
    var age = 20

    function bar () {
        console.log(name)
        console.log(age)
    }
    return bar
} // 第二行至第八行为闭包函数 name 和 age 上升为自有变量

var fn = foo()
fn()

fn函数调用完毕之后,foo函数会自动销毁,但foo函数中的变量name和age不会被销毁,因为在bar函数内部进行了访问,并且根据垃圾回收机制,被另一个作用域引用的变量不会被回收。除非bar函数解除调用才能销毁。
如果该函数使用的次数很少,不进行销毁的话就会变为闭包产生的内存泄漏。
说了这么多解决办法是什么呢?只需将该函数赋值为null即可。
示例代码如下(承接上一个代码片段):

fn = null  // 阻止内存泄漏

闭包可能会造成内存泄漏,但不是一定会造成。

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-04-23 11:07:26  更:2022-04-23 11:08:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 13:38:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码