Javascript $scope.$on(';$destroy';,…)';谁的事件处理程序被销毁了?

Javascript $scope.$on(';$destroy';,…)';谁的事件处理程序被销毁了?,javascript,angularjs,angularjs-scope,destroy,Javascript,Angularjs,Angularjs Scope,Destroy,今天我遇到了一个很有棱角的问题,我找不到答案。从文档中,您可以在“$destroy”上注册一个事件处理程序,该事件处理程序在作用域销毁之前调用。这样,您可以取消注册事件处理程序,如下所示: var deregister = $scope.$on('myCustomEvent', function () { // do some crazy stuff }); $scope.$on('$destroy', function () { deregister(); }); 但是,('

今天我遇到了一个很有棱角的问题,我找不到答案。从文档中,您可以在
“$destroy”
上注册一个事件处理程序,该事件处理程序在作用域销毁之前调用。这样,您可以取消注册事件处理程序,如下所示:

var deregister = $scope.$on('myCustomEvent', function () {
    // do some crazy stuff
});
$scope.$on('$destroy', function () {
    deregister();
});
但是,('$destroy',…)上的
$scope.$on必须创建自己的处理程序。它是自动销毁的,还是必须执行以下操作才能销毁

var deregister = $scope.$on('myCustomEvent', function () {
    // do some crazy stuff
});
var deregisterDestroy = $scope.$on('$destroy', function () {
    deregister();
    deregisterDestroy();
});
答案实际上是“可能”,这取决于你所说的自动销毁的意思。如果我们查看作用域方法的源代码,我们可以看到,当
$destroy
事件向下广播到整个子作用域时,实际的
$destroy
方法除了在初始作用域上之外,不会在任何作用域上调用。这意味着在子作用域上永远不会发生对属性的实际清除和置零

这不会泄漏内存的原因是,一旦在作用域上调用了
$destroy
,它就会与父作用域分离,因此可以进行垃圾收集,因为它不应该再具有任何到GC根的路径。这一逻辑同样适用于所有子作用域,因为它们也不应该有到GC根的路径


你的例子是安全的;我自己也是这样做的,以便在必要时清理自己的处理程序,并且不会遇到任何类型的无限循环。

是的,它会被销毁-当然,如果它引用了处理程序本身外部的任何东西(以及它在其闭包中的所有东西),就不会被释放(就像其他任何地方一样)我想接下来的问题是:(a)是否有必要取消注册,以及(b)如果有,你甚至可以按照我上面写的方式取消注册吗?Naa,你只需要无限递归-你不需要取消注册,范围就会被破坏。我相信很快,有更多时间的人会在这里给出一个体面而详细的答案:)使用var-deregister=$scope.$on为该侦听器取消注册函数。。。