code: function(name, listener) {
          var namedListeners = this.$$listeners[name];
          if (!namedListeners) {
            this.$$listeners[name] = namedListeners = [];
          }
          namedListeners.push(listener);
  
          return function() {
            arrayRemove(namedListeners, listener);
          };
        }
docs: @ngdoc function
  @name ng.$rootScope.Scope#$on
  @methodOf ng.$rootScope.Scope
  @function
  
  @description
  Listen on events of a given type. See {@link ng.$rootScope.Scope#$emit $emit} for discussion of
  event life cycle.
  
  @param {string} name Event name to listen on.
  @param {function(event)} listener Function to call when the event is emitted.
  @returns {function()} Returns a deregistration function for this listener.
  
  The event listener function format is: `function(event, args...)`. The `event` object
  passed into the listener has the following attributes:
  
  - `targetScope` - {Scope}: the scope on which the event was `$emit`-ed or `$broadcast`-ed.
  - `currentScope` - {Scope}: the current scope which is handling the event.
  - `name` - {string}: Name of the event.
  - `stopPropagation` - {function=}: calling `stopPropagation` function will cancel further event propagation
  (available only for events that were `$emit`-ed).
  - `preventDefault` - {function}: calling `preventDefault` sets `defaultPrevented` flag to true.
  - `defaultPrevented` - {boolean}: true if `preventDefault` was called.