VBScript中对象的破坏顺序是什么?

bac*_*car 5 windows vbscript destructor object-lifetime

.vbs中的对象以什么顺序销毁?

也就是说,给定这些全局变量:

Set x = New Xxx
Set y = New Yyy
Run Code Online (Sandbox Code Playgroud)

我对以下任何一个问题的答案感兴趣.

  1. 对于.VBS中实现的类的实例,将以什么顺序Class_Terminate调用?粗略的戳戳建议创造的顺序(而不是逆序!),但这有保证吗?

    编辑:我知道Class_Terminate将在释放对象的最后一次引用时调用.我的意思是:x和y的发布顺序是什么,是否有保证?为简单起见,假设x和y是对其各自对象的唯一引用.

  2. 对象的类型是否重要?例如,如果我在.VBS中实现的类与其他COM对象混合在一起,例如Scripting.FileSystemObject.

    编辑:我知道COM库可能会设置自己的内部循环引用,脚本主机引擎一无所知; 我有兴趣探索可能影响第一个问题答案的内容.

  3. 上述不同的答案如果x和y是Sub或Function的本地而不是全局?
  4. 是否取决于退出是正常的,例外还是通过WScript.Quit?(在后一种情况下,似乎Class_Terminate在退出之前仍然会调用任何未完成的对象,但这些可能会导致报告错误).
  5. 什么时候WScript对象被破坏?
  6. 脚本是否重要?(wscript.exe vs cscript.exe与调用Web主机引擎无关)
  7. JScript的对象销毁模型与VBScript的不同吗?

我可以凭经验找到其中一些问题的答案,但我对它们中的任何一个是否得到保证 /记录感兴趣.

即使你只知道一些答案 - 或进一步的相关问题,请发帖.

Eri*_*ert 9

我在VBScript中设计并实现了这个功能.

大多数答案都在我的文章中,Mark引用,但只是为了澄清:

将以什么顺序调用Class_Terminate?

通常在释放对象的最后一个引用时立即调用终结符.但是,由于循环引用和其他问题,依赖确定性的终止顺序通常是一个非常糟糕的主意.

粗略的戳戳建议创造的顺序(而不是逆序!),但这有保证吗?

正如我在文章中提到的,当发动机关闭时,终止未终止的对象.作为实现细节,终止队列按创建对象的顺序执行.但是,这是一个您不应该依赖的未记录的实现细节.

对象的类型是否重要?例如,如果我在.VBS中实现了与其他COM对象混合的类,例如Scripting.FileSystemObject.

它可以.在那些在不可预测的时间被拆除的对象中可能存在循环引用.

当程序退出时,我正在考虑全局范围内的对象 - 对于例如函数范围的对象,它是否不同?

我不明白这个问题.你能澄清一下吗?

是否取决于退出是正常的,异常还是通过WScript.Quit?(在后一种情况下,似乎在退出之前仍然会在任何未完成的对象上调用Class_Terminate,但是这些可能会导致报告错误).

这很重要,是的.VBScript不保证终结器始终运行.例如,拥有发动机的主机可以通过"不能快速失败"的方式关闭其过程,这种方式不能保证干净地关闭发动机.(如果发生灾难性故障,这有时是可取的;如果您不知道什么是错的,那么有时运行终止代码会使问题变得更糟,而不是更好.)

调用Quit时,Windows脚本宿主会尝试干净地关闭引擎.

什么时候WScript对象被破坏?

当Windows脚本宿主进程终止逻辑运行时.

脚本是否重要?(wscript.exe vs cscript.exe与调用Web主机引擎无关)

是的,这很重要.

JScript的对象销毁模型与VBScript的不同吗?

是的,非常如此.

从我工作的时期开始的JScript"Classic"(2001年之前)使用了一个非确定性的标记和清除垃圾收集器,它在脚本对象之间处理循环引用,但不处理脚本和浏览器对象之间的循环引用.更新版本的JScript"Classic"有一个修改过的垃圾收集器,它可以处理脚本和浏览器对象之间的循环引用(尽管它不一定能检测涉及JScript对象和第三方ActiveX对象的循环.)

IE 9的JScript版本有一个完全重写的垃圾收集器,它使用了截然不同的技术; 我和它的设计师聊了一下,但我没有足够的技术知识来讨论它在任何深度上的特征.

JScript .NET当然使用CLR垃圾收集器.

我可以问你为什么关心这些东西吗?

另外,请注意我十多年来没有看过这段代码; 以适当的怀疑态度来解决所有这些问题.我的记忆可能有问题.