The source code

    /**
     * @ignore
     * base custom event mechanism for kissy
     * @author yiminghe@gmail.com
     */
    KISSY.add('event/base/observable', function (S) {

        /**
         * base custom event for registering and un-registering observer for specified event.
         * @class KISSY.Event.ObservableEvent
         * @private
         * @param {Object} cfg custom event's attribute
         */
        function ObservableEvent(cfg) {
            var self = this;
            S.mix(self, cfg);
            self.reset();
            /**
             * current event type
             * @cfg {String} type
             */
        }

        ObservableEvent.prototype = {

            constructor: ObservableEvent,

            /**
             * whether current event has observers
             * @return {Boolean}
             */
            hasObserver: function () {
                return !!this.observers.length;
            },

            /**
             * reset current event's status
             */
            reset: function () {
                var self = this;
                self.observers = [];
            },

            /**
             * remove one observer from current event's observers
             * @param {KISSY.Event.Observer} s
             */
            removeObserver: function (s) {
                var self = this,
                    i,
                    observers = self.observers,
                    len = observers.length;
                for (i = 0; i < len; i++) {
                    if (observers[i] == s) {
                        observers.splice(i, 1);
                        break;
                    }
                }
                self.checkMemory();
            },

            /**
             * check memory after detach
             * @private
             */
            checkMemory: function () {

            },

            /**
             * Search for a specified observer within current event's observers
             * @param {KISSY.Event.Observer} observer
             * @return {Number} observer's index in observers
             */
            findObserver: function (observer) {
                var observers = this.observers, i;

                for (i = observers.length - 1; i >= 0; --i) {
                    /*
                     If multiple identical EventListeners are registered on the same EventTarget
                     with the same parameters the duplicate instances are discarded.
                     They do not cause the EventListener to be called twice
                     and since they are discarded
                     they do not need to be removed with the removeEventListener method.
                     */
                    if (observer.equals(observers[i])) {
                        return i;
                    }
                }

                return -1;
            }
        };

        return ObservableEvent;

    });