The source code

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

        // IE doesn't include non-breaking-space (0xa0) in their \s character
        // class (as required by section 7.2 of the ECMAScript spec), we explicitly
        // include it in the regexp to enforce consistent cross-browser behavior.
        var RE_TRIM = /^[\s\xa0]+|[\s\xa0]+$/g,
            trim = String.prototype.trim,
            SUBSTITUTE_REG = /\\?\{([^{}]+)\}/g,
            EMPTY = '';

        S.mix(S, {
            /**
             * Removes the whitespace from the beginning and end of a string.
             * @method
             * @member KISSY
             */
            trim: trim ?
                function (str) {
                    return str == null ? EMPTY : trim.call(str);
                } :
                function (str) {
                    return str == null ? EMPTY : (str + '').replace(RE_TRIM, EMPTY);
                },

            /**
             * Substitutes keywords in a string using an object/array.
             * Removes undefined keywords and ignores escaped keywords.
             * @param {String} str template string
             * @param {Object} o json data
             * @member KISSY
             * @param {RegExp} [regexp] to match a piece of template string
             */
            substitute: function (str, o, regexp) {
                if (typeof str != 'string' || !o) {
                    return str;
                }

                return str.replace(regexp || SUBSTITUTE_REG, function (match, name) {
                    if (match.charAt(0) === '\\') {
                        return match.slice(1);
                    }
                    return (o[name] === undefined) ? EMPTY : o[name];
                });
            },

            /** uppercase first character.
             * @member KISSY
             * @param s
             * @return {String}
             */
            ucfirst: function (s) {
                s += '';
                return s.charAt(0).toUpperCase() + s.substring(1);
            },
            /**
             * test whether a string start with a specified substring
             * @param {String} str the whole string
             * @param {String} prefix a specified substring
             * @return {Boolean} whether str start with prefix
             * @member KISSY
             */
            startsWith: function (str, prefix) {
                return str.lastIndexOf(prefix, 0) === 0;
            },

            /**
             * test whether a string end with a specified substring
             * @param {String} str the whole string
             * @param {String} suffix a specified substring
             * @return {Boolean} whether str end with suffix
             * @member KISSY
             */
            endsWith: function (str, suffix) {
                var ind = str.length - suffix.length;
                return ind >= 0 && str.indexOf(suffix, ind) == ind;
            }

        });
    })(KISSY);