gup*_*ron 4 javascript garbage-collection memory-management node.js eventemitter
如果我有这样的代码:
const EventEmitter = require('events');
class Bot extends EventEmitter {
sendMessage() {
// do something
this.emit('messageSent', 'user123');
}
}
class Controller {
loadBot() {
const bot = new Bot();
bot.on('messageSent', userId => {
// do something
});
}
}
Run Code Online (Sandbox Code Playgroud)
bot里面创建的对象loadBot会立即销毁吗?或者稍后通过垃圾收集?
或者实例是否会Controller持有对它的引用,以便bot在Controller实例被销毁之前永远不会被销毁?
单独注册一个事件侦听器并不能阻止它被垃圾收集。某些东西实际上必须具有对Bot对象本身的引用(以便实际可以从中发出事件),以免被垃圾收集。
在您的 Controller 类中,如果没有其他任何内容引用Bot您创建的实例,那么它将有资格进行垃圾回收。这是有道理的,因为如果没有任何东西可以引用它,那么其他任何东西都不能使用它,也没有任何东西可以调用它的自定义方法sendMessage()。
正如您现在拥有的代码一样,您的bot变量只是loadBot()方法内部的一个局部变量,没有其他任何东西可以引用它。因此,只要loadBot()方法执行完毕,bot变量就可以进行垃圾回收,因为任何地方都没有代码可以再次使用或访问该对象。这使它有资格进行垃圾收集。
从您的代码看来,您可能打算将该bot变量作为Controller对象的实例变量。如果是这种情况,那么只要某些人引用了您的Controller对象,那么该bot对象也会保持活动状态。
所以,看起来你可能打算这样做:
const EventEmitter = require('events');
class Bot extends EventEmitter {
sendMessage() {
// do something
this.emit('messageSent', 'user123');
}
}
class Controller {
loadBot() {
this.bot = new Bot();
this.bot.on('messageSent', userId => {
// do something
});
}
send() {
this.bot.sendMessage();
}
}
var c = new Controller();
c.loadBot();
Run Code Online (Sandbox Code Playgroud)
在这里,您bot在Controller对象的实例数据中保留了对变量的引用,因此可以通过其他代码(如send()方法)或访问.bot您Controller对象上的属性的任何其他代码访问它。