JS常用功能扩展方法,大家要用自己拿



(function () {

    //#region Date对象相关扩展

    /*
     * 格式化
     * @param {Date} date 日期
     * @param {String} fmt 格式
     * @return {String} 日期
     */
    Date.format = function (date, fmt) {
        if (!(date instanceof Date)) {
            throw new Error("type of date is wrong.");
        }

        if (typeof (fmt) !== "string") {
            throw new Error("type of fmt is wrong.");
        }

        var _getHours = function (tag) {
            var hours = date.getHours();
            return hours === 0 ? 0 :
                hours > 12 ? hours - 12 : hours;
        }

        var o = {
            "M+": date.getMonth() + 1,                      //月份    
            "d+": date.getDate(),                           //日    
            "H+": date.getHours(),                          //小时(0-23)  
            "h+": _getHours("h"),                           //小时(1-12)     
            "m+": date.getMinutes(),                        //分    
            "s+": date.getSeconds(),                        //秒      
        };

        if (/(y+)/.test(fmt)) {
            fmt = fmt.replace(RegExp.$1, RegExp.$1.length <= 2 ?
                date.getFullYear().addPreZero(4).slice(-2) :
                date.getFullYear().addPreZero(4).slice(-4));
        }

        if (/(f+)/.test(fmt)) {
            fmt = fmt.replace(RegExp.$1,
                date.getMilliseconds().addPreZero(3).substring(0, RegExp.$1.length));
        }

        for (var k in o) {
            if (new RegExp("(" + k + ")").test(fmt)) {
                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ?
                    o[k].toString() : o[k].addPreZero(2));
            }
        }

        return fmt;
    }

    /*
     * 格式化
     * @param {String} fmt 格式
     * @return {String} 日期
     */
    Date.prototype.format = function (fmt) {
        return Date.format(this, fmt);
    };


    /*
     * 增加秒
     * @param {Date} date 日期
     * @param {Number} value 值
     * @return {Date} 日期
     */
    Date.addSecond = function (date, value) {
        if (!(date instanceof Date)) {
            throw new Error("type of date is wrong.");
        }

        if (typeof (value) !== "number") {
            throw new Error("type of value is wrong.");
        }

        return new Date(date.getTime() + 1000 * value);
    }

    /*
     * 增加秒
     * @param {Number} value 值
     * @return {Date} 日期
     */
    Date.prototype.addSecond = function (value) {
        return Date.addSecond(this, value);
    }


    /*
     * 增加分钟
     * @param {Date} date 日期
     * @param {Number} value 值
     * @return {Date} 日期
     */
    Date.addMinutes = function (date, value) {
        if (!(date instanceof Date)) {
            throw new Error("type of date is wrong.");
        }

        if (typeof (value) !== "number") {
            throw new Error("type of value is wrong.");
        }

        return new Date(date.getTime() + 60 * 1000 * value);
    }

    /*
     * 增加分钟
     * @param {Number} value 值
     * @return {Date} 日期
     */
    Date.prototype.addMinutes = function (value) {
        return Date.addMinutes(this, value);
    }


    /*
     * 增加小时
     * @param {Date} date 日期
     * @param {Number} value 值
     * @return {Date} 日期
     */
    Date.addHours = function (date, value) {
        if (!(date instanceof Date)) {
            throw new Error("type of date is wrong.");
        }

        if (typeof (value) !== "number") {
            throw new Error("type of value is wrong.");
        }

        return new Date(date.getTime() + 60 * 60 * 1000 * value);
    }

    /*
     * 增加小时
     * @param {Number} value 值
     * @return {Date} 日期
     */
    Date.prototype.addHours = function (value) {
        return Date.addHours(this, value);
    }


    /*
     * 增加天
     * @param {Date} date 日期
     * @param {Number} value 值
     * @return {Date} 日期
     */
    Date.addDays = function (date, value) {
        if (!(date instanceof Date)) {
            throw new Error("type of date is wrong.");
        }

        if (typeof (value) !== "number") {
            throw new Error("type of value is wrong.");
        }

        return new Date(date.getTime() + 24 * 60 * 60 * 1000 * value);
    }

    /*
     * 增加天
     * @param {Number} value 值
     * @return {Date} 日期
     */
    Date.prototype.addDays = function (value) {
        return Date.addDays(this, value);
    }


    /*
     * 增加月份
     * @param {Date} date 日期
     * @param {Number} value 值
     * @return {Date} 日期
     */
    Date.addMonths = function (date, value) {
        if (!(date instanceof Date)) {
            throw new Error("type of date is wrong.");
        }

        if (typeof (value) !== "number") {
            throw new Error("type of value is wrong.");
        }

        //保存天数
        var day = date.getDate();

        var ret = new Date(date.getTime());
        ret.setDate(1); //把日期初始化为1号,计算后重新赋值
        ret.setMonth(date.getMonth() + value);
        ret.setDate(Math.min(day, ret.getDaysInMonth()));

        return ret;
    }

    /*
     * 增加月份
     * @param {Number} value 增加的值
     * @return {Date} 日期
     */
    Date.prototype.addMonths = function (value) {
        return Date.addMonths(this, value);
    }


    /*
     * 增加年份
     * @param {Date} date 日期
     * @param {Number} value 增加的值
     * @return {Date} 日期
     */
    Date.addYears = function (date, value) {
        if (!(date instanceof Date)) {
            throw new Error("type of date is wrong.");
        }

        if (typeof (value) !== "number") {
            throw new Error("type of value is wrong.");
        }

        //保存天数
        var day = date.getDate();

        var ret = new Date(date.getTime());
        ret.setDate(1); //把日期初始化为1号,计算后重新赋值
        ret.setYear(date.getFullYear() + value);
        ret.setDate(Math.min(day, ret.getDaysInMonth()));

        return ret;
    }

    /*
     * 增加年份
     * @param {Number} value 增加的值
     * @return {Date} 日期
     */
    Date.prototype.addYears = function (value) {
        return Date.addYears(this, value);
    }


    /*
     * 是否是润年
     * @param {Date} date 日期
     * @return {Boolean} 结果
     */
    Date.isLeapYear = function (date) {
        if (!(date instanceof Date)) {
            throw new Error("type of date is wrong.");
        }

        var year = date.getFullYear();
        return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
    };

    /*
     * 是否是润年
     * @return {Boolean} 结果
     */
    Date.prototype.isLeapYear = function () {
        return Date.isLeapYear(this);
    };


    /*
     * 获取月份有多少天
     * @param {Date} date 日期
     * @return {Number} 天数
     */
    Date.getDaysInMonth = function (date) {
        if (!(date instanceof Date)) {
            throw new Error("type of date is wrong.");
        }

        var month = date.getMonth();
        var days = date.isLeapYear() ? 29 : 28;
        return [31, days, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
    };

    /*
     * 获取月份有多少天
     * @return {Number} 天数
     */
    Date.prototype.getDaysInMonth = function () {
        return Date.getDaysInMonth(this);
    };


    /*
     * 获取日期星期
     * @param {Date} date 日期
     * @param {Array} [array] 返回结果数组,如["星期一","星期二",...]
     * @return {String} 星期字符串
     */
    Date.getDayOfWeek = function (date, array) {
        if (!(date instanceof Date)) {
            throw new Error("type of date is wrong.");
        }

        if (array && !(array instanceof Array)) {
            throw new Error("type of array is wrong.");
        }

        array = array || new Array("日", "一", "二", "三", "四", "五", "六");
        var week = date.getDay();

        return array[week];
    }

    /*
     * 获取日期星期
     * @param {Array} [array] 返回结果数组,如["星期一","星期二",...]
     * @return {String} 星期字符串
     */
    Date.prototype.getDayOfWeek = function (array) {
        return Date.getDayOfWeek(this, array);
    }


    /*
     * 获取时间间隔
     * @param {Date} startDate 开始日期
     * @param {Date} endDate 结束日期
     * @param {String} [interval] 默认值"T","D":精确到天、"H":精确到小时、"M"精确到分钟、"S"精确到秒、"T"精确到毫秒
     * @return {Number} 间隔数
     */
    Date.getTimeSpan = function (startDate, endDate, interval) {
        if (!(startDate instanceof Date)) {
            throw new Error("type of startDate is wrong.");
        }

        if (!(endDate instanceof Date)) {
            throw new Error("type of endDate is wrong.");
        }

        if (interval && interval.toUpperCase() !== "D" && interval.toUpperCase() !== "H" && interval.toUpperCase() !== "M" &&
            interval.toUpperCase() !== "S" && interval.toUpperCase() !== "T") {
            throw new Error("interval is wrong.");
        }

        interval = interval ? interval.toUpperCase() : 'T';
        var objInterval = { 'D': 1000 * 60 * 60 * 24, 'H': 1000 * 60 * 60, 'M': 1000 * 60, 'S': 1000, 'T': 1 };
        return Math.round((endDate - startDate) / eval('(objInterval.' + interval + ')'));
    }

    /*
     * 获取时间间隔
     * @param {Date} endDate 结束日期
     * @param {String} [interval] 默认值"D","D":精确到天、"H":精确到小时、"M"精确到分钟、"S"精确到秒、"T"精确到毫秒
     * @return {Number} 间隔数
     */
    Date.prototype.getTimeSpan = function (endDate, interval) {
        return Date.getTimeSpan(this, endDate, interval);
    }

    //#endregion

    //#region String对象相关扩展

    /*
     * Json日期字符串转换成日期 
     * 格式一:2017-01-13T17:25:20.869212 或 2017-01-13T17:25:20.869212+08:00
     * 格式二:/Date(12321212111)/
     * 格式三:yyyy/MM/dd、yyyy-MM-dd 等
     * @param {String} dateString 日期字符串
     * @return {Date} 日期
     */
    String.jsonStrToDate = function (dateString) {
        if (typeof (dateString) !== "string" && !(dateString instanceof String)) {
            throw new Error("type of dateString is wrong.");
        }

        if (dateString.indexOf('Date') >= 0) {
            return new Date(parseInt(dateString.substring(6, dateString.length - 2)));
        }

        if (dateString.indexOf('T') >= 0) {
            if (dateString.indexOf('+') < 0) {
                dateString += "+08:00";
            }

            return new Date(dateString);
        }
        else {
            if (Date.parse(dateString)) {
                return new Date(dateString);
            }
            else {
                return new Date(dateString.replace(/-/gi, "\/"));
            }
        }
    }

    /*
     * Json日期字符串转换成日期 
     * 格式一:2017-01-13T17:25:20.869212 或 2017-01-13T17:25:20.869212+08:00
     * 格式二:/Date(12321212111)/
     * 格式三:yyyy/MM/dd、yyyy-MM-dd 等
     * @return {Date} 日期
     */
    String.prototype.jsonStrToDate = function () {
        return String.jsonStrToDate(this);
    }


    /*
     * 去除字符串头部空格或指定字符 
     * @param {String} str 字符串
     * @param {String} [c] 指定字符(字符串)
     * @return {String} 字符串
     */
    String.trimStart = function (str, c) {
        if (typeof (str) !== "string" && !(str instanceof String)) {
            throw new Error("type of str is wrong.");
        }

        if (c && typeof (c) !== "string") {
            throw new Error("type of c is wrong.");
        }

        var regExp;
        if (!c) {
            regExp = new RegExp(/^\s*/);
        }
        else {
            regExp = new RegExp("^" + c);
        }

        return str.replace(regExp, '');
    }

    /*
     * 去除字符串头部空格或指定字符 
     * @param {String} [c] 指定字符(字符串)
     * @return {String} 字符串
     */
    String.prototype.trimStart = function (c) {
        return String.trimStart(this, c);
    }


    /*
     * 去除字符串尾部空格或指定字符 
     * @param {String} str 字符串
     * @param {String} [c] 指定字符(字符串)
     * @return {String} 字符串
     */
    String.trimEnd = function (str, c) {
        if (typeof (str) !== "string" && !(str instanceof String)) {
            throw new Error("type of str is wrong.");
        }

        if (c && typeof (c) !== "string") {
            throw new Error("type of c is wrong.");
        }

        var regExp;
        if (!c) {
            regExp = new RegExp(/\s*$/);
        }
        else {
            regExp = new RegExp(c + "$");
        }

        return str.replace(regExp, '');
    }

    /*
     * 去除字符串尾部空格或指定字符 
     * @param {String} [c] 指定字符(字符串)
     * @return {String} 字符串
     */
    String.prototype.trimEnd = function (c) {
        return String.trimEnd(this, c);
    }


    /*
     * 去除字符串首尾空格或指定字符 
     * @param {String} str 字符串
     * @param {String} [c] 指定字符(字符串)
     * @return {String} 字符串
     */
    String.trim = function (str, c) {
        if (typeof (str) !== "string" && !(str instanceof String)) {
            throw new Error("type of str is wrong.");
        }

        if (c && typeof (c) !== "string") {
            throw new Error("type of c is wrong.");
        }


        return str.trimStart(c).trimEnd(c);
    }

    /*
     * 去除字符串尾部空格或指定字符 
     * @param {String} [c] 指定字符(字符串)
     * @return {String} 字符串
     */
    String.prototype.trim = function (c) {
        return String.trim(this, c);
    }


    /*
     * 是否由指定字符串开始 
     * @param {String} str 字符串
     * @param {String} s 指定字符串
     * @return {Boolean} 结果
     */
    String.startWith = function (str, s) {
        if (typeof (str) !== "string" && !(str instanceof String)) {
            throw new Error("type of str is wrong.");
        }

        if (typeof (s) !== "string") {
            throw new Error("type of s is wrong.");
        }

        if (s.length > str.length) {
            return false;
        }

        return str.substr(0, s.length) === s;
    }

    /*
     * 是否由指定字符串开始 
     * @param {String} s 指定字符串
     * @return {Boolean} 结果
     */
    String.prototype.startWith = function (s) {
        return String.startWith(this, s);
    }


    /*
     * 是否由指定字符串结束
     * @param {String} str 字符串
     * @param {String} s 指定字符串
     * @return {Boolean} 结果
     */
    String.endWith = function (str, s) {
        if (typeof (str) !== "string" && !(str instanceof String)) {
            throw new Error("type of str is wrong.");
        }

        if (typeof (s) !== "string") {
            throw new Error("type of s is wrong.");
        }

        if (s.length > str.length) {
            return false;
        }

        return str.substring(str.length - s.length) === s;
    }

    /*
     * 是否由指定字符串结束
     * @param {String} s 指定字符串
     * @return {Boolean} 结果
     */
    String.prototype.endWith = function (s) {
        return String.endWith(this, s);
    }


    /*
     * 是否包含指定字符串
     * @param {String} str 字符串
     * @param {String} s 指定字符串
     * @return {Boolean} 结果
     */
    String.contains = function (str, s) {
        if (typeof (str) !== "string" && !(str instanceof String)) {
            throw new Error("type of str is wrong.");
        }

        if (typeof (s) !== "string") {
            throw new Error("type of s is wrong.");
        }

        return str.indexOf(s) !== -1;
    }

    /*
     * 是否包含指定字符串
     * @param {String} s 指定字符串
     * @return {Boolean} 结果
     */
    String.prototype.contains = function (s) {
        return String.contains(this, s);
    }


    /*
     * 插入指定字符串
     * @param {String} str 字符串
     * @param {String} s 指定字符串
     * @param {Number} [index] 指定位置
     * @return {String} 字符串
     */
    String.insert = function (str, s, index) {
        if (typeof (str) !== "string" && !(str instanceof String)) {
            throw new Error("type of str is wrong.");
        }

        if (typeof (s) !== "string") {
            throw new Error("type of s is wrong.");
        }

        if (index && typeof (index) !== "number") {
            throw new Error("type of index is wrong.");
        }

        if (!index) {
            index = 0;
        }
        else if (index > str.length) {
            index = str.length;
        }

        return str.substring(0, index) + s + str.substring(index);
    }

    /*
     * 插入指定字符串
     * @param {String} s 指定字符串
     * @param {Number} [index] 指定位置
     * @return {String} 字符串
     */
    String.prototype.insert = function (s, index) {
        return String.insert(this, s, index);
    }


    /*
     * 截取字符串
     * @param {String} str 字符串
     * @param {Number} s 指定长度
     * @param {String} [sign] 替换截取的符号,默认为"..."
     * @return {String} 字符串
     */
    String.cutString = function (str, len, sign) {
        if (typeof (str) !== "string" && !(str instanceof String)) {
            throw new Error("type of str is wrong.");
        }

        if (typeof (len) !== "number") {
            throw new Error("type of len is wrong.");
        }

        if (sign && typeof (sign) !== "string") {
            throw new Error("type of sign is wrong.");
        }

        //取得指定长度的字符串
        var _cutString = function (str, len) {
            var strLen = str.length; // 原字符串长度 
            var stringn;// 截取后的字符串
            var flag = "1";
            var lenCount = 0;
            var ret = false;

            if (strLen <= len / 2) {
                stringn = str;
                ret = true;
            }

            if (!ret) {
                for (var i = 0; i < strLen; i++) {
                    if (_isFull(str.charAt(i))) {
                        lenCount += 2;
                    } else {
                        lenCount += 1;
                    }

                    if (lenCount > len) {
                        stringn = str.substring(0, i);
                        ret = true;
                        break;
                    }
                    else if (lenCount == len) {
                        stringn = str.substring(0, i + 1);
                        ret = true;
                        break;
                    }
                }
            }

            if (!ret) {
                stringn = str;
            }

            if (stringn.length == strLen) {
                flag = "0";
            }

            return { "Stringn": stringn, "Flag": flag };
        }

        //判断是否为全角
        var _isFull = function (char) {
            for (var i = 0; i < char.strLen; i++) {
                if ((char.charCodeAt(i) > 128)) {
                    return true;
                } else {
                    return false;
                }
            }
        }

        var _ret = _cutString(str, len);
        return _ret.Flag == "1" ? _ret.Stringn + (sign || "...") : _ret.Stringn + "";
    }

    /*
     * 截取字符串
     * @param {Number} s 指定长度
     * @param {String} [sign] 替换截取的符号,默认为"..."
     * @return {String} 字符串
     */
    String.prototype.cutString = function (len, sign) {
        return String.cutString(this, len, sign);
    }


    /*
     * 格式化
     * @param {String} str 字符串
     * @param {Object|Array} [args] 格式化内容
     * @return {String} 字符串
     */
    String.format = function (str, args) {
        if (typeof (str) !== "string" && !(str instanceof String)) {
            throw new Error("type of str is wrong.");
        }

        if (typeof (args) == "object") {
            for (var key in args) {
                if (args[key] !== null && args[key] !== undefined) {
                    var regExp = new RegExp("\\{" + key + "\\}", "g");
                    str = str.replace(regExp, args[key])
                };
            }
        }
        else {
            for (var i = 1, max = arguments.length; i < max; i++) {
                if (arguments[i] !== null && arguments[i] !== undefined) {
                    var regExp = new RegExp("\\{" + (i - 1) + "\\}", 'g');
                    str = str.replace(regExp, arguments[i]);
                }
            }
        }

        return str;
    }

    /*
     * 格式化
     * @param {Object|Array} [args] 格式化内容
     * @return {String} 字符串
     */
    String.prototype.format = function (args) {
        return String.format(this, typeof (args) === "object" ? args : arguments);
    }

    //#endregion

    //#region Array对象相关扩展

    /*
     * 获取满足表达式的数组元素索引
     * @param {Array} array 数组对象
     * @param {Function} predicate 表达式
     * @return {Number} 索引,未找到满足表达式的元素时返回-1
     */
    Array.findIndex = function (array, predicate) {
        if (!(array instanceof Array)) {
            throw new Error("type of array is wrong.");
        }

        if (typeof (predicate) !== 'function') {
            throw new TypeError('type of predicate is wrong.');
        }

        for (var i = 0, len = array.length; i < len; i++) {
            if (predicate.call(arguments[2], array[i], i, array)) {
                return i;
            }
        }

        return -1;
    }

    /*
     * 获取满足表达式的数组元素索引
     * @param {Function} predicate 表达式
     * @return {Number} 索引,未找到满足表达式的元素时返回-1
     */
    Array.prototype.findIndex = function (predicate) {
        return Array.findIndex(this, predicate, arguments[1]);
    };


    /*
     * 是否存在满足表达式的数组元素
     * @param {Array} array 数组对象
     * @param {Function} predicate 表达式
     * @return {Boolean} 结果
     */
    Array.any = function (array, predicate) {
        if (!(array instanceof Array)) {
            throw new Error("type of array is wrong.");
        }

        if (typeof (predicate) !== 'function') {
            throw new TypeError('type of predicate is wrong.');
        }

        return Array.findIndex(array, predicate, arguments[2]) > -1;
    };

    /*
     * 是否存在满足表达式的数组元素
     * @param {Function} predicate 表达式
     * @return {Boolean} 结果
     */
    Array.prototype.any = function (predicate) {
        return Array.any(this, predicate, arguments[1]);
    };


    /*
     * 获取满足表达式的第一个或默认数组元素
     * @param {Array} array 数组对象
     * @param {Function} predicate 表达式
     * @return {Object} 元素
     */
    Array.firstOrDefault = function (array, predicate) {
        if (!(array instanceof Array)) {
            throw new Error("type of array is wrong.");
        }

        if (typeof (predicate) !== 'function') {
            throw new TypeError('type of predicate is wrong.');
        }

        var index = Array.findIndex(array, predicate, arguments[2]);
        return index == -1 ? null : array[index];
    }

    /*
     * 获取满足表达式的第一个或默认数组元素
     * @param {Function} predicate 表达式
     * @return {Object} 元素
     */
    Array.prototype.firstOrDefault = function (predicate) {
        return Array.firstOrDefault(this, predicate, arguments[1]);
    }


    /*
     * 获取满足表达式的第一个数组元素
     * @param {Array} array 数组对象
     * @param {Function} predicate 表达式
     * @return {Object} 元素
     */
    Array.find = function (array, predicate) {
        if (!(array instanceof Array)) {
            throw new Error("type of array is wrong.");
        }

        if (typeof (predicate) !== 'function') {
            throw new TypeError('type of predicate is wrong.');
        }

        return Array.firstOrDefault(array, predicate, arguments[2]);
    }

    /*
     * 获取满足表达式的第一个数组元素
     * @param {Function} predicate 表达式
     * @return {Object} 元素
     */
    Array.prototype.find = function (predicate) {
        return Array.find(this, predicate, arguments[1]);
    }


    /*
     * 筛选满足表达式的数组元素
     * @param {Array} array 数组对象
     * @param {Function} predicate 表达式
     * @return {Array} 数组
     */
    Array.where = function (array, predicate) {
        if (!(array instanceof Array)) {
            throw new Error("type of array is wrong.");
        }

        if (typeof (predicate) !== 'function') {
            throw new TypeError('type of predicate is wrong.');
        }

        //如果浏览器支持reduce,使用reduce,效率高
        if (typeof (array.reduce) === "function") {
            return array.reduce(function (ret, element, index) {
                if (predicate.call(arguments[2], element, index, array)) {
                    ret.push(element);
                }

                return ret;
            }, []);
        }
        else {
            var ret = [];
            for (var i = 0, len = array.length; i < len; i++) {
                var element = array[i];
                if (predicate.call(arguments[2], element, i, array)) {
                    ret.push(element);
                }
            }

            return ret;
        }
    }

    /*
     * 筛选满足表达式的数组元素
     * @param {Function} predicate 表达式
     * @return {Array} 数组
     */
    Array.prototype.where = function (predicate) {
        return Array.where(this, predicate, arguments[1]);
    }


    /*
     * 获取满足表达式的数组元素的计数
     * @param {Array} array 数组对象
     * @param {Function} predicate 表达式
     * @return {Number} 计数
     */
    Array.count = function (array, predicate) {
        if (!(array instanceof Array)) {
            throw new Error("type of array is wrong.");
        }

        if (typeof (predicate) !== 'function') {
            throw new TypeError('type of predicate is wrong.');
        }

        return Array.where(array, predicate, arguments[2]).length;
    }

    /*
     * 获取满足表达式的数组元素的计数
     * @param {Function} predicate 表达式
     * @return {Number} 计数
     */
    Array.prototype.count = function (predicate) {
        return Array.count(this, predicate, arguments[1]);
    }


    /*
     * 获取满足表达式的数组元素的数组
     * @param {Array} array 数组对象
     * @param {Function} predicate 表达式
     * @return {Array} 数组
     */
    Array.findAll = function (array, predicate) {
        if (!(array instanceof Array)) {
            throw new Error("type of array is wrong.");
        }

        if (typeof (predicate) !== 'function') {
            throw new TypeError('type of predicate is wrong.');
        }

        return Array.where(array, predicate, arguments[2]);
    }

    /*
     * 获取满足表达式的数组元素的数组
     * @param {Function} predicate 表达式
     * @return {Array} 数组
     */
    Array.prototype.findAll = function (predicate) {
        return Array.findAll(this, predicate, arguments[1]);
    }


    /*
     * 获取通过选择器转换的数组
     * @param {Array} array 数组对象
     * @param {Function} selector 选择器
     * @return {Array} 数组
     */
    Array.select = function (array, selector) {
        if (!(array instanceof Array)) {
            throw new Error("type of array is wrong.");
        }

        if (typeof (selector) !== 'function') {
            throw new TypeError('type of selector is wrong.');
        }

        //如果浏览器支持reduce,使用reduce,效率高
        if (typeof (array.reduce) === "function") {
            return array.reduce(function (ret, element, index) {
                ret.push(selector.call(arguments[2], element, index, array));
                return ret;
            }, []);
        }
        else {
            var ret = [];
            for (var i = 0, len = array.length; i < len; i++) {
                ret.push(selector.call(arguments[2], array[i], i, array))
            }

            return ret;
        }
    }

    /*
     * 获取通过选择器转换的数组
     * @param {Function} selector 选择器
     * @return {Array} 数组
     */
    Array.prototype.select = function (selector) {
        return Array.select(this, selector, arguments[1]);
    }


    /*
     * 排序(升序)
     * @param {Array} array 数组对象
     * @param {Function} keySelector key选择器
     * @param {Function} [comparer] 比较器
     * @return {Array} 数组
     */
    Array.orderBy = function (array, keySelector, comparer) {
        if (!(array instanceof Array)) {
            throw new Error("type of array is wrong.");
        }

        if (typeof (keySelector) !== 'function') {
            throw new TypeError('type of keySelector is wrong.');
        }

        if (comparer && typeof (comparer) !== 'function') {
            throw new TypeError('type of comparer is wrong.');
        }

        array.sort(function (x, y) {
            var v1 = keySelector(x)
            var v2 = keySelector(y)
            if (comparer) {
                return comparer(v1, v2);
            }
            else {
                return (v1 > v2) ? 1 : -1;
            }
        });

        return array;
    }

    /*
     * 排序(升序)
     * @param {Array} array 数组对象
     * @param {Function} keySelector key选择器
     * @param {Function} [comparer] 比较器
     * @return {Array} 数组
     */
    Array.prototype.orderBy = function (keySelector, comparer) {
        return Array.orderBy(this, keySelector, comparer);
    }


    /*
     * 排序(降序)
     * @param {Array} array 数组对象
     * @param {Function} keySelector key选择器
     * @param {Function} [comparer] 比较器
     * @return {Array} 数组
     */
    Array.orderByDescending = function (array, keySelector, comparer) {
        if (!(array instanceof Array)) {
            throw new Error("type of array is wrong.");
        }

        if (typeof (keySelector) !== 'function') {
            throw new TypeError('type of keySelector is wrong.');
        }

        if (comparer && typeof (comparer) !== 'function') {
            throw new TypeError('type of comparer is wrong.');
        }

        array.sort(function (x, y) {
            var v1 = keySelector(x)
            var v2 = keySelector(y)
            if (comparer) {
                return -comparer(v1, v2);
            }
            else {
                return (v1 < v2) ? 1 : -1;
            }
        });

        return array;
    }

    /*
     * 排序(降序)
     * @param {Function} keySelector key选择器
     * @param {Function} [comparer] 比较器
     * @return {Array} 数组
     */
    Array.prototype.orderByDescending = function (keySelector, comparer) {
        return Array.orderByDescending(this, keySelector, comparer);
    }


    /*
     * 分组
     * @param {Array} array 数组对象
     * @param {Function} keySelector key选择器
     * @return {Array} 分组
     */
    Array.groupBy = function (array, keySelector) {
        if (!(array instanceof Array)) {
            throw new Error("type of array is wrong.");
        }

        if (typeof (keySelector) !== 'function') {
            throw new TypeError('type of keySelector is wrong.');
        }

        //如果浏览器支持reduce,使用reduce,效率高
        if (typeof (array.reduce) === "function") {
            var keys = [];
            return array.reduce(function (groups, element, index) {
                var key = JSON.stringify(keySelector.call(arguments[1], element, index, array))
                var index = keys.findIndex(function (x) { return x === key });

                if (index < 0) {
                    index = keys.push(key) - 1;
                }

                if (!groups[index]) {
                    groups[index] = [];
                }

                groups[index].push(element);
                return groups;
            }, []);
        }
        else {
            var groups = [];
            var keys = [];
            for (var i = 0, len = array.length; i < len; i++) {
                var key = JSON.stringify(keySelector.call(arguments[1], array[i], i, array));
                var index = keys.findIndex(function (x) { return x === key });

                if (index < 0) {
                    index = keys.push(key) - 1;
                }

                if (!groups[index]) {
                    groups[index] = [];
                }

                groups[index].push(array[i]);
            }

            return groups;
        }
    }

    /*
     * 分组
     * @param {Function} keySelector key选择器
     * @return {Array} 分组
     */
    Array.prototype.groupBy = function (keySelector) {
        return Array.groupBy(this, keySelector)
    }


    /*
     * 求和
     * @param {Array} array 数组对象
     * @param {Function} [selector] 选择器
     * @return {Object} 结果
     */
    Array.sum = function (array, selector) {
        if (!(array instanceof Array)) {
            throw new Error("type of array is wrong.");
        }

        if (selector && typeof (selector) !== 'function') {
            throw new TypeError('type of selector is wrong.');
        }

        var ret;
        for (var i = 0, len = array.length; i < len; i++) {
            if (i == 0) {
                if (selector) {
                    ret = selector.call(arguments[2], array[i], i, array);
                }
                else {
                    ret = array[i]
                }
            }
            else {
                if (selector) {
                    ret += selector.call(arguments[2], array[i], i, array);
                }
                else {
                    ret += array[i]
                }
            }
        }

        return ret;
    }

    /*
     * 求和
     * @param {Function} [selector] 选择器
     * @return {Array} 结果
     */
    Array.prototype.sum = function (selector) {
        return Array.sum(this, selector, arguments[1]);
    }

    /*
     * 包含
     * @param {Array} array 数组对象
     * @param {Number|String} value 值
     * @return {Boolen} 结果
     */
    Array.contains = function (array, value) {
        if (!(array instanceof Array)) {
            throw new Error("type of array is wrong.");
        }

        for (var i = 0, len = array.length; i < len; i++) {
            if (array[i] == value) {
                return true;
            }
        }

        return false;
    };

    /*
     * 包含
     * @param {Number|String} value 值
     * @return {Boolen} 结果
     */
    Array.prototype.contains = function (value) {
        return Array.contains(this, value);
    }

    /*
     * 移除满足表达式的数组元素
     * @param {Array} array 数组对象
     * @param {Function} predicate 表达式
     */
    Array.removeAll = function (array, predicate) {
        if (!(array instanceof Array)) {
            throw new Error("type of array is wrong.");
        }

        if (typeof (predicate) !== 'function') {
            throw new TypeError('type of predicate is wrong.');
        }

        var index;
        do {
            index = Array.findIndex(array, predicate, arguments[2])
            if (index >= 0) {
                array.splice(index, 1);
            }
        }
        while (index >= 0);
    }

    /*
     * 移除满足表达式的数组元素
     * @param {Function} predicate 表达式
     */
    Array.prototype.removeAll = function (predicate) {
        Array.removeAll(this, predicate, arguments[1]);
    }


    /*
     * 移除数组元素
     * @param {Array} array 数组对象
     * @param {Object} element 数组元素
     */
    Array.remove = function (array, element) {
        if (!(array instanceof Array)) {
            throw new Error("type of array is wrong.");
        }

        var index = Array.findIndex(array, function (x) {
            return x === element;
        });

        if (index >= 0) {
            array.splice(index, 1);
            return true;
        }
        else {
            return false;
        }
    }

    /*
     * 移除数组元素
     * @param {Object} element 数组元素
     */
    Array.prototype.remove = function (element) {
        return Array.remove(this, element);
    }


    /*
     * 移除特定索引数组元素
     * @param {Array} array 数组对象
     * @param {Number} index 索引
     */
    Array.removeAt = function (array, index) {
        if (!(array instanceof Array)) {
            throw new Error("type of array is wrong.");
        }

        array.splice(index, 1);
    }

    /*
     * 移除特定索引数组元素
     * @param {Number} index 索引
     */
    Array.prototype.removeAt = function (index) {
        Array.removeAt(this, index);
    }


    /*
     * 移除范围数组元素
     * @param {Array} array 数组对象
     * @param {Number} index 开始索引
     * @param {Number} count 删除的个数
     */
    Array.removeRange = function (array, index, count) {
        if (!(array instanceof Array)) {
            throw new Error("type of array is wrong.");
        }

        array.splice(index, count);
    }

    /*
     * 移除范围数组元素
     * @param {Number} index 开始索引
     * @param {Number} count 删除的个数
     */
    Array.prototype.removeRange = function (index, count) {
        Array.removeRange(this, index, count);
    }

    //#endregion

    //#region Number对象相关扩展

    /* 
     * 加法函数,用来得到精确的加法结果 
     * javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。
     * @param {Number} a 参与计算数
     * @param {Number} b 参与计算数
     * @return {Number} 相对精确结果 
     */
    Number.add = function (a, b) {
        if (typeof (a) !== "number" && !(a instanceof Number)) {
            throw new Error("type of a is wrong.");
        }

        if (typeof (b) !== "number") {
            throw new Error("type of b is wrong.");
        }

        var c, d, e;
        try {
            c = a.toString().split(".")[1].length;
        } catch (f) {
            c = 0;
        }
        try {
            d = b.toString().split(".")[1].length;
        } catch (f) {
            d = 0;
        }

        return e = Math.pow(10, Math.max(c, d)), (Number.mul(a, e) + Number.mul(b, e)) / e;
    }

    /* 
     * 加法函数,用来得到精确的加法结果 
     * javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。
     * @param {Number} b 参与计算数
     * @return {Number} 相对精确结果 
     */
    Number.prototype.add = function (b) {
        return Number.add(this, b);
    };


    /* 
     * 减法函数,用来得到精确的减法结果 
     * javascript的加法结果会有误差,在两个浮点数相减的时候会比较明显。
     * @param {Number} a 参与计算数
     * @param {Number} b 参与计算数
     * @return {Number} 相对精确结果 
     */
    Number.sub = function (a, b) {
        if (typeof (a) !== "number" && !(a instanceof Number)) {
            throw new Error("type of a is wrong.");
        }

        if (typeof (b) !== "number") {
            throw new Error("type of b is wrong.");
        }

        var c, d, e;
        try {
            c = a.toString().split(".")[1].length;
        } catch (f) {
            c = 0;
        }
        try {
            d = b.toString().split(".")[1].length;
        } catch (f) {
            d = 0;
        }

        return e = Math.pow(10, Math.max(c, d)), (Number.mul(a, e) - Number.mul(b, e)) / e;
    }

    /* 
     * 减法函数,用来得到精确的减法结果 
     * javascript的加法结果会有误差,在两个浮点数相减的时候会比较明显。
     * @param {Number} b 参与计算数
     * @return {Number} 相对精确结果 
     */
    Number.prototype.sub = function (b) {
        return Number.sub(this, b);
    };


    /* 
     * 乘法函数,用来得到精确的乘法结果  
     * javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。
     * @param {Number} a 参与计算数
     * @param {Number} b 参与计算数
     * @return {Number} 相对精确结果 
     */
    Number.mul = function (a, b) {
        if (typeof (a) !== "number" && !(a instanceof Number)) {
            throw new Error("type of a is wrong.");
        }

        if (typeof (b) !== "number") {
            throw new Error("type of b is wrong.");
        }

        var c = 0, d = a.toString(), e = b.toString();
        try {
            c += d.split(".")[1].length;
        } catch (f) { }
        try {
            c += e.split(".")[1].length;
        } catch (f) { }

        return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c);
    }

    /* 
     * 乘法函数,用来得到精确的乘法结果  
     * javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。
     * @param {Number} b 参与计算数
     * @return {Number} 相对精确结果 
     */
    Number.prototype.mul = function (b) {
        return Number.mul(this, b);
    };


    /* 
     * 除法函数,用来得到精确的除法结果   
     * javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显
     * @param {Number} a 参与计算数
     * @param {Number} b 参与计算数
     * @return {Number} 相对精确结果 
     */
    Number.div = function (a, b) {
        if (typeof (a) !== "number" && !(a instanceof Number)) {
            throw new Error("type of a is wrong.");
        }

        if (typeof (b) !== "number") {
            throw new Error("type of b is wrong.");
        }

        if (b === 0) {
            throw new Error("dividend cannot be 0.");
        }

        var c, d, e = 0, f = 0;
        try {
            e = a.toString().split(".")[1].length;
        } catch (g) { }
        try {
            f = b.toString().split(".")[1].length;
        } catch (g) { }
        return c = Number(a.toString().replace(".", "")), d = Number(b.toString().replace(".", "")), Number.mul(c / d, Math.pow(10, f - e));
    }

    /* 
     * 除法函数,用来得到精确的除法结果   
     * javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显
     * @param {Number} b 参与计算数
     * @return {Number} 相对精确结果 
     */
    Number.prototype.div = function (b) {
        return Number.div(this, b);
    };


    /*
     * 补零
     * @param {Number} num 数字
     * @param {Number} length 总长度
     * @return {String} 字符串
     */
    Number.addPreZero = function (num, length) {
        if (typeof (num) !== "number" && !(num instanceof Number)) {
            throw new Error("type of num is wrong.");
        }

        if (typeof (length) !== "number") {
            throw new Error("type of length is wrong.");
        }

        if (length > num.toString().length) {
            return (Array(length).join('0') + num).slice(-length);
        }
        else {
            return num.toString();
        }
    }

    /*
     * 补零
     * @param {Number} length 总长度
     * @return {String} 字符串
     */
    Number.prototype.addPreZero = function (length) {
        return Number.addPreZero(this, length);
    }

    //#endregion

}())
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容