js 的类有没有析构函数,如何进行资源释放??

2021-09-03 09:27:44 +08:00
 James369
查了半天没看到 js 类有析构函数,那么类对象在销毁的时候,如何把申请的资源释放呢,否则可能内存泄漏。

比如,考虑以下场景,有一些学生类 Student,以及一个图书馆类 Library 。
1. 开始创建了若干学生 Student 对象,然后做了一些操作,向 Library 借了几本书。
2. 过了一会,有些学生对象做了一些其它操作(比如上课、睡觉,但就是没有还书),然后自动释放了(离开了变量作用域,生存周期结束了)。
3. 此时虽然说 Student 自动释放了,但是还书操作没有显式调用,造成书籍未还。

所以,如果 Student 类有析构函数,我就可以在析构函数中进行还书等的资源释放。正规语言都有析构函数,现在怎么处理,?
7881 次点击
所在节点    程序员
79 条回复
janus77
2021-09-03 09:55:18 +08:00
业务问题就用业务办法,自己手动释放。你说的“离开作用域会自己释放”某种程度上就是不对的一个观念。
kop1989
2021-09-03 09:56:08 +08:00
第一段说“内存泄漏”。
第二段转头就说“书未还”(业务问题)了。

楼主真的想明白你到底要干什么了么。

1 、析构函数你用来处理业务?
2 、有回收机制的语言怎么会有狭义的、原教旨主义的析构函数?
3 、建议你去了解一下带有 GC 机制语言的“销毁事件”的特点与注意事项。
Chingim
2021-09-03 10:01:18 +08:00
析构函数式用来处理系统资源的, 不是用来处理业务逻辑的

这个例子, library 应该保留 student 的引用, 不要让他们跑了
aguesuka
2021-09-03 10:01:41 +08:00
这是语言糟粕, 连 Java 的析构函数 finalize 从 9 也开始过时了.
runze
2021-09-03 10:05:28 +08:00
ss99604
2021-09-03 10:09:47 +08:00
WeakRef 、FinalizationRegistry
agagega
2021-09-03 10:10:11 +08:00
楼上真有人觉得析构函数这个 C++/Rust/Swift 里重中之重的概念是没有意义的糟粕吗.. RAII 不是管理内存这么简单。
qW7bo2FbzbC0
2021-09-03 10:36:58 +08:00
我原来一直以为析构=untuple
jadehare
2021-09-03 10:47:59 +08:00
你可以上课,睡觉的时候让他们还书,或者删除引用的时候直接让 library 去找每个学生要书
shawckzh
2021-09-03 11:13:34 +08:00
GC 语言不应该 RAII,不然 go 为啥会有 defer

LZ 要是觉得显式调用麻烦,建议自己写个简单的 defer,就是函数退出时隐式调用呗,wrap 一下就行
qq73666
2021-09-03 11:26:47 +08:00
@darknoll oc,swift 不服
cyberscorpio
2021-09-03 11:32:09 +08:00
不用的时候将其置为 null 即可
runze
2021-09-03 11:32:58 +08:00
@agagega #27 但这是 JS 呀!
一般都是对标 Py 、PHP,跟 Java 、Go 对比已经算是离谱了,为什么要跟 C++、Rust 对比?
yannxia
2021-09-03 11:39:29 +08:00
@agagega 对于带 GC 的语言,业务逻辑的释放,是应该在自己的代码设计里面,至于 C++ 里面也不太建议析构逻辑上的东西。
推荐都是 close hook
chenmobuys
2021-09-03 11:47:43 +08:00
@runze 实际上 PHP 也有析构函数
chairuosen
2021-09-03 11:55:28 +08:00
系统内置的没有,如果硬要用,只能把对象用 defineProperty 或者 Proxy 存在另一个对象上,然后监听置空时主动调一下旧数据的 destroy 方法
Pythoner666666
2021-09-03 12:11:31 +08:00
我都写 JS 了 还要我手动还回收内存?
EPr2hh6LADQWqRVH
2021-09-03 12:26:33 +08:00
我现在的项目里就包含这种代码,
目前在 js 环境里需要用到 WeakRef 和相关的 FinalizationRegistry,详情

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry
jrtzxh020
2021-09-03 12:40:17 +08:00
感觉是你的业务逻辑设计有问题
ysc3839
2021-09-03 13:17:05 +08:00
有 GC 的语言不能用 RAII,比如 Python, Java, JavaScript 都不可以用 RAII,因为离开作用域后对象不一定立即释放,析构函数不能及时执行,可能会出现预料之外的情况。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/799592

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX