The source code

    /**
     * @ignore
     * function utilities of lang
     * @author yiminghe@gmail.com
     *
     */
    (function (S, undefined) {

        function bindFn(r, fn, obj) {
            var slice = [].slice,
                args = slice.call(arguments, 3),
                fNOP = function () {
                },
                bound = function () {
                    var inArgs = slice.call(arguments);
                    return fn.apply(
                        this instanceof fNOP ? this : obj,
                        (r ? inArgs.concat(args) : args.concat(inArgs))
                    );
                };
            fNOP.prototype = fn.prototype;
            bound.prototype = new fNOP();
            return bound;
        }

        S.mix(S, {
            /**
             * empty function
             * @member KISSY
             */
            noop: function () {
            },
            /**
             * Creates a new function that, when called, itself calls this function in the context of the provided this value,
             * with a given sequence of arguments preceding any provided when the new function was called.
             * refer: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
             * @param {Function} fn internal called function
             * @param {Object} obj context in which fn runs
             * @param {*...} var_args extra arguments
             * @member KISSY
             * @return {Function} new function with context and arguments
             */
            bind: bindFn(0, bindFn, null, 0),

            /**
             * Creates a new function that, when called, itself calls this function in the context of the provided this value,
             * with a given sequence of arguments preceding any provided when the new function was called.
             * refer: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
             * @param {Function} fn internal called function
             * @param {Object} obj context in which fn runs
             * @param {*...} var_args extra arguments
             * @member KISSY
             * @return {Function} new function with context and arguments
             */
            rbind: bindFn(0, bindFn, null, 1),

            /**
             * Executes the supplied function in the context of the supplied
             * object 'when' milliseconds later. Executes the function a
             * single time unless periodic is set to true.
             *
             * @param fn {Function|String} the function to execute or the name of the method in
             * the 'o' object to execute.
             *
             * @param [when=0] {Number} the number of milliseconds to wait until the fn is executed.
             *
             * @param {Boolean} [periodic] if true, executes continuously at supplied interval
             * until canceled.
             *
             * @param {Object} [context] the context object.
             *
             * @param [data] that is provided to the function. This accepts either a single
             * item or an array. If an array is provided, the function is executed with
             * one parameter for each array item. If you need to pass a single array
             * parameter, it needs to be wrapped in an array [myarray].
             *
             * @return {Object} a timer object. Call the cancel() method on this object to stop
             * the timer.
             *
             * @member KISSY
             */
            later: function (fn, when, periodic, context, data) {
                when = when || 0;
                var m = fn,
                    d = S.makeArray(data),
                    f,
                    r;

                if (typeof fn == 'string') {
                    m = context[fn];
                }

                if (!m) {
                    S.error('method undefined');
                }

                f = function () {
                    m.apply(context, d);
                };

                r = (periodic) ? setInterval(f, when) : setTimeout(f, when);

                return {
                    id: r,
                    interval: periodic,
                    cancel: function () {
                        if (this.interval) {
                            clearInterval(r);
                        } else {
                            clearTimeout(r);
                        }
                    }
                };
            },

            /**
             * Throttles a call to a method based on the time between calls.
             * @param {Function} fn The function call to throttle.
             * @param {Object} [context] context fn to run
             * @param {Number} [ms] The number of milliseconds to throttle the method call.
             * Passing a -1 will disable the throttle. Defaults to 150.
             * @return {Function} Returns a wrapped function that calls fn throttled.
             * @member KISSY
             */
            throttle: function (fn, ms, context) {
                ms = ms || 150;

                if (ms === -1) {
                    return (function () {
                        fn.apply(context || this, arguments);
                    });
                }

                var last = S.now();

                return (function () {
                    var now = S.now();
                    if (now - last > ms) {
                        last = now;
                        fn.apply(context || this, arguments);
                    }
                });
            },

            /**
             * buffers a call between a fixed time
             * @param {Function} fn
             * @param {Number} ms
             * @param {Object} [context]
             * @return {Function} Returns a wrapped function that calls fn buffered.
             * @member KISSY
             */
            buffer: function (fn, ms, context) {
                ms = ms || 150;

                if (ms === -1) {
                    return function () {
                        fn.apply(context || this, arguments);
                    };
                }
                var bufferTimer = null;

                function f() {
                    f.stop();
                    bufferTimer = S.later(fn, ms, 0, context || this, arguments);
                }

                f.stop = function () {
                    if (bufferTimer) {
                        bufferTimer.cancel();
                        bufferTimer = 0;
                    }
                };

                return f;
            }
        });
    })(KISSY);