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

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

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

所以,如果 Student 类有析构函数,我就可以在析构函数中进行还书等的资源释放。正规语言都有析构函数,现在怎么处理,?
8464 次点击
所在节点    程序员
79 条回复
fyxtc
2021-09-03 19:55:13 +08:00
楼主应该是学生吧?析构和 GC 保证的应该是 Student 销毁的时候,再次引用实例 stu 能保证不可能取到曾经存在的任何信息(当然包括借书信息),反之就是内存泄露(所以这就是为什么 C/C++有内存泄露问题,因为需要你自己去手动控制)。而既然你是手动调用让 stu 去借了,自然应用由你来手动归还,这不是语言层面的问题,所以不应该依赖任何语言设计的语法,换言之,就算有析构,你肯定也需要在特定的生命周期内去显式调用析构(通过 delete 之类)而不应该依赖自动调用。

就拿你举的例子来说,如果不是通过 new 创建的,那么离开作用域自动析构,那么你就应该在离开作用域的时候调用还书,很直接的线性关系。如果是 new 出来或者有存在其他地方的引用的,那么肯定是在之后某个通知下触发学生销毁了,那么就应该在那里调用还书,而不是依赖析构。
ragnaroks
2021-09-03 20:05:20 +08:00
这个事情让我想到 blazor 官方示例最开始在 page 里面有个 timer 更新页面时间(表现双向更新效果),但是因为 blazor 没有“主动释放”导致大量访问后就会塞爆内存。

btw,现在也没有 OnDestory 的事件,但是可以实现 IDispose 接口
namelosw
2021-09-03 22:44:52 +08:00
> 正规语言都有析构函数

你这说得义正辞严的。我猜你用过的正规语言只有一个哈哈哈哈。

连 C 都没有不用析构函数,Rust 都不怎么用析构函数,更别提 Java 和 JavaScript 了。
aloxaf
2021-09-03 22:59:13 +08:00
@namelosw Rust 哪有「不怎么用」,明明到处都是
zxCoder
2021-09-03 23:09:23 +08:00
这个跟析构函数没有关系吧,这个是业务逻辑的问题
WilliamYang
2021-09-03 23:37:57 +08:00
又一个 XY 问题,你需要的是业务怎么处理,而不是问有没有析构函数
ipwx
2021-09-04 01:06:30 +08:00
gc 语言应该要显式 close,因为你无法控制 gc 什么时候调用析构函数,是巨大的 bug 隐患。
TypeError
2021-09-04 02:18:00 +08:00
内存释放靠 gc
资源释放靠手动或者语法保证( Python with/Golang defer )

https://stackoverflow.com/questions/62879698/any-tips-on-context-manager-similar-to-python-in-javascript
liberize
2021-09-04 09:24:41 +08:00
说白了,这些没析构函数的语言就是得提供一个 close 接口,手动调用 close
zjsxwc
2021-09-04 10:16:48 +08:00
GC 语言( PHP\JAVA )的析构函数(__destruct/finalize ) != RAII 语言( C++)的析构函数 (~xx ) != ARC 语言( oc/swift )的析构函数( dealloc/deinit ) != 所有权语言( Rust )的析构函数( drop )
zjsxwc
2021-09-04 10:20:40 +08:00
上面 4 类语言中,只有 GC 语言存在 STW 卡顿现象。
Building
2021-09-04 10:41:07 +08:00
在释放函数执行还书操作本身就不合理吧。
1. 书和学生互相引用,这样根本走不到释放函数。
2. 书和学生无互相引用,学生释放了并不会影响还书。
3. 如果必需要执行还书操作,书和学生不相互引用,却能提前释放学生,这个在设计上没有问腿吗
wangxin13g
2021-09-04 16:43:44 +08:00
析构函数不应该有任何业务层面上的操作。
qq1009479218
2021-09-04 18:35:33 +08:00
手动析构
aleen42
2021-09-04 21:30:28 +08:00
lbyo
2021-09-05 15:07:00 +08:00
@qrobot #47

> 有一些语言是需要开发者手动明确进行处理的,例如 rust c/c++

Ownership is Rust’s most unique feature, and it enables Rust to make memory safety guarantees without needing a garbage collector.
KuroNekoFan
2021-09-05 19:42:49 +08:00
楼主是把 OO 和编程语言能力搞混了吗
liuhan907
2021-09-05 20:48:14 +08:00
@GeruzoniAnsasu
一圈回复看下来,raii 都已经是时代的眼泪了。
mxT52CRuqR6o5
2022-02-28 21:07:23 +08:00

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

https://tanronggui.xyz/t/799592

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

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

© 2021 V2EX