@ngdoc event
@name $rootScope.Scope#$destroy
@eventType broadcast on scope being destroyed

@description
Broadcasted when a scope and its children are being destroyed.

Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to
clean up DOM bindings before an element is removed from the DOM.
 
@ngdoc method
@name $rootScope.Scope#$destroy
@kind function

@description
Removes the current scope (and all of its children) from the parent scope. Removal implies
that calls to {@link ng.$rootScope.Scope#$digest $digest()} will no longer
propagate to the current scope and its children. Removal also implies that the current
scope is eligible for garbage collection.

The `$destroy()` is usually used by directives such as
{@link ng.directive:ngRepeat ngRepeat} for managing the
unrolling of the loop.

Just before a scope is destroyed, a `$destroy` event is broadcasted on this scope.
Application code can register a `$destroy` event handler that will give it a chance to
perform any necessary cleanup.

Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to
clean up DOM bindings before an element is removed from the DOM.
function() {
        // we can't destroy the root scope or a scope that has been already destroyed
        if (this.$$destroyed) return;
        var parent = this.$parent;

        this.$broadcast('$destroy');
        this.$$destroyed = true;
        if (this === $rootScope) return;

        forEach(this.$$listenerCount, bind(null, decrementListenerCount, this));

        // sever all the references to parent scopes (after this cleanup, the current scope should
        // not be retained by any of our references and should be eligible for garbage collection)
        if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling;
        if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling;
        if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling;
        if (this.$$nextSibling) this.$$nextSibling.$$prevSibling = this.$$prevSibling;


        // All of the code below is bogus code that works around V8's memory leak via optimized code
        // and inline caches.
        //
        // see:
        // - https://code.google.com/p/v8/issues/detail?id=2073#c26
        // - https://github.com/angular/angular.js/issues/6794#issuecomment-38648909
        // - https://github.com/angular/angular.js/issues/1313#issuecomment-10378451

        this.$parent = this.$$nextSibling = this.$$prevSibling = this.$$childHead =
            this.$$childTail = this.$root = null;

        // don't reset these to null in case some async task tries to register a listener/watch/task
        this.$$listeners = {};
        this.$$watchers = this.$$asyncQueue = this.$$postDigestQueue = [];

        // prevent NPEs since these methods have references to properties we nulled out
        this.$destroy = this.$digest = this.$apply = noop;
        this.$on = this.$watch = this.$watchGroup = function() { return noop; };
      }