首页 > 代码库 > Js中常用的字符串,数组,函数扩展

Js中常用的字符串,数组,函数扩展

由于最近辞职在家,自己的时间相对多一点。所以就根据prototytpeJS的API,结合自己正在看的司徒大神的《javascript框架设计》,整理了下Js中常用一些字符串,数组,函数扩展,一来可以练练手,二来也锻炼下自己的代码能力。由于代码里面的注释自认为已经非常详细,所以就直接贴代码了。

1. 字符串扩展:

;(function() {    var method, stringExtends = {        /**         * 删除字符串开始和结尾的空白         * @returns {string}         */        strip: function() {            return this.replace(/^\s+|\s+$/gm, ‘‘);        },        /**         * 删除字符串左边的空白         * @returns {string}         */        stripLeft: function() {            return this.replace(/^\s+/, ‘‘);        },        /**         * 删除字符右边的空白         * @returns {string}         */        stripRight: function() {            return this.replace(/\s+$/, ‘‘)        },        /**         * 判断一个字符串是否是空串;空串或只包含空白字符时返回true         * @returns {boolean}         */        blank: function() {            return this.strip().length === 0;        },        /**         * 将CSS中属性名转换成JS中的样式名,background-color -> backgroundColor         * @returns {string}         */        camelize: function() {            return this.replace(/(\-\w)/g, function(match) {                return match.slice(1).toUpperCase();            })        },        /**         * 将一个字符串的首字母大写,其它字符小写         * @returns {string}         */        capitalize: function() {            return this.strip().replace(/^(\w{1})(.*)/g, function(match, g1, g2) {                return g1.toUpperCase() + g2.toLowerCase();            });        },        /**         * 将字符串中的下划线转换成中划线         * @returns {string}         */        dasherize: function() {            return this.replace(/\_/g, ‘-‘);        },        /**         * 检测字符串是否是空串         * @returns {boolean}         */        empty: function() {            return this.length === 0;           /* ‘‘.empty(); //-> true            ‘  ‘.empty();//-> false*/        },        /**         * 检测字符串是否是以特定的字符串结尾         * @param {String} target         * @returns {boolean}         */        endsWith: function(target) {            return (new RegExp(target+‘$‘)).test(this);            //return this.slice(-target.length) === target;        },        /**         * 检测字符串是否是以特定的字符串开始         * @param {String} target         * @returns {boolean}         */        startsWith: function(target) {            return (new RegExp(‘^‘+target)).test(this);        },        /**         * 检测字符串是否包含特定的字符串         * @param {String} target         * @returns {boolean}         */        contains: function(target) {            return this.indexOf(target) !== -1;        },        /**         *         * @param {number} n - 要重复的次数         * @returns {string}         */        times: function(n) {            //return new Array(n+1).join(this);            /*return [].join.call({                length:n + 1            }, this);*/            //使用二分法            var ret, flag = false, str = this.toString();            if(n === 0)                return ‘‘;            if(n === 1)                return str;            if(n % 2) {                //奇数                n = n - 1;                flag = true;            }            ret = str.times(n / 2);            return flag ? (ret + ret + str) : (ret + ret);        },        /**         * 对字符串中的特殊字符进行转义,避免XSS         */        escapeHTML:function() {            //转义后的字符是可以直接设置成innerHTML的值。            //replace(/&/g, ‘&amp;‘)这条replace()调用一定要写在所有的特殊字符转义的前面,不然转换后有&符号的会再被转一次            return this.replace(/&/g, ‘&amp;‘)                    .replace(/\</g, ‘&lt;‘)                    .replace(/\>/g, ‘&gt;‘)                    .replace(/\‘/g, ‘&#39;‘)                    .replace(/\"/g, ‘&quot;‘);            /*var strArr = this.split(‘‘);            for(var pos = 0, l = strArr.length, tmp; pos < l; pos++) {                tmp = strArr[pos];                switch(tmp) {                    case ‘<‘:                        replaceArr(strArr, pos, ‘&lt;‘);                        break;                    case ‘>‘:                        replaceArr(strArr, pos, ‘&gt;‘);                        break;                    case ‘\‘‘:                        replaceArr(strArr, pos, ‘&#39;‘);                        break;                    case ‘\"‘:                        replaceArr(strArr, pos, ‘&quot;‘);                        break;                    case ‘&‘:                        replaceArr(strArr, pos, ‘&amp;‘);                        break;                    default:;                }            }            return strArr.join(‘‘);            function replaceArr(arr, pos, item) {                return arr.splice(pos, 1, item);            }*/        },        /**         * 对字符串进行反转义         */        unescapeHTML: function() {            return this.replace(/&amp;/, ‘&‘)                .replace(/&lt;/g, ‘<‘)                .replace(/&gt;/g, ‘>‘)                .replace(/&#39;/g, ‘\‘‘)                .replace(/&quot;/g, ‘\"‘)                .replace(/&#(\d+)/g, function($0, $1) {                    return String.formCharCode(parseInt($1, 10));                });        },        /**         * 取得字符串的逆序         * @returns {string}         */        reverse: function() {            return (this.toString()).split(‘‘).reverse().join(‘‘);        },        /**         * 截取字符串,并可以指定填充后缀         * @param {number} [length = 30] - 截取长度,默认为30个字符         * @param {string} [suffix = ‘...‘] - 填充后缀,默认为‘...‘         * @returns {string}         */        truncate: function(length, suffix) {            var ret = this.toString();            length = length || 30;            suffix = suffix || ‘...‘;            //如果字符串不大于length, 直接返回字符串            if(ret.length < length) {                return ret;            }            return ret.slice(0, length - suffix.length) + suffix;        },        /**         * 去掉字符串中的html标签         * @returns {string}         */        stripTags: function() {            return this.replace(/(\<\w+\s?.*?\>)|(\<\/\w+\s?.*?\>)/g, function() {                return ‘‘;            });        },        /**         * 去掉字符串中的脚本         * @returns {string}         */        stripScripts: function() {            return this.replace(/\<script\>.*?\<\/script\>/, function() {                return ‘‘;            })        }    };    for(method in stringExtends) {        stringExtends.hasOwnProperty(method) &&        typeof String.prototype[method] !== ‘function‘ &&        (String.prototype[method] = stringExtends[method]);    }})();

 

2. 数组扩展

 

;(function() {    var method, arrayExtends = {        /**         * 为数组增加ES5中的迭代方法:forEach, map, filter, every, some         * W3C标准规定:每个方法接收两个参数,要在每一项上运行的回调和(可选的)运行回调时函数的上下文         * 其中回调函数的参数中会包含三个参数:数组项的值,位置,和数组本身         */        /**         * 对数组的每一项执行回调,这个方法没返回值         */        forEach: function(fn, ctx) {            for(var i = 0, l = this.length; i < l; i++) {                fn.call(ctx || null, this[i], i, this);            }        },        /**         * 对数组每项运行回调函数,返回由回调函数的结果组成的数组         */        map: function(fn, ctx) {            var ret = [];            for(var i = 0, l = this.length; i < l; i++) {                ret.push(fn.call(ctx || null, this[i], i, this));            }            return ret;        },        /**         * 对数组每项运行回调函数,返回使回调函数返回值为true组成的数组         */        filter: function(fn, ctx) {            var ret = [];            for(var i = 0, l = this.length; i < l; i++) {                fn.call(ctx || null, this[i], i, this) &&                ret.push(this[i]);            }            return ret;        },        /**         * 对数组每项运行回调函数,如果所有的回调函数都返回true, 则返回true         */        every: function(fn, ctx) {            for(var i = 0, l = this.length; i < l; i++) {                !!fn.call(ctx || null, this[i], i, this) === false;                return false;            }            return true;        },        /**         * 对数组每项运行回调函数,如果有一项回调函数返回true, 则返回true         */        some: function(fn, ctx) {            for(var i = 0, l = this.length; i < l; i++) {                !!fn.call(ctx || null, this[i], i, this) === true;                return true;            }            return false;        },        /**         * 从左向右(顺利)对数组的每一项(从第二项开始,即下标为1)运行回调函数。         * 回调函数包含四个参数prev(上一次回调的返回值), cur(当前数组项), index(当前数组项的索引), self(数组本身)         * @param {Function} callback         * @returns {*}         */        reduce: function(callback) {            var i = 1, //从数组第二个元素开始                l = this.length,                callbackRet = this[0];            for(; i < l; ++i) {                callbackRet = callback.call(null, callbackRet, this[i], i, this);            }            return callbackRet;        },        /**         * 从右向左(逆序)对数组的每一项(从倒数第二项开始,即下标为arr.length - 2)运行回调函数。         * 回调函数包含四个参数prev(上一次回调的返回值), cur(当前数组项), index(当前数组项的索引), self(数组本身)         * @param {Function} callback         * @returns {*}         */        reduceRight: function(callback) {            var l = this.length,                i = l - 2, //从数组倒数第二个元素开始                callbackRet = this[l - 1]; //回调初始值为数组最后一个元素的值            for(; i >= 0; --i) {                callbackRet = callback.call(null, callbackRet, this[i], i, this);            }            return callbackRet;        },        /**         * 返回目标值在数组中第一次出现的位置,搜索从左向右进行。         * 如果目标值在数组中不存在,则返回-1。可以指定一个搜索起始位置。默认为0         * @param {Number} target         * @param {Number} [start = 0] - start默认为0         * @returns {Number}         */        indexOf: function(target, start) {            var l = this.length,                start = ~~start;//可以指定一个搜索起始位置。默认为0。start不传,默认为undefined,~~undefined -> 0            if(start < 0)                start = 0;//如果指定的搜索位置小于0,则设置其开始搜索位置为0            for(; start < l; ++start) {                if(this[start] === target)                    return start;            }            return -1;        },        /**         * 返回目标值在数组中的位置。搜索从右向左进行         * 如果目标值在数组中不存在,则返回-1。可以指定一个搜索起始位置。默认为数组长度         * @param {Number} target         * @param {Number} [start = arr.length] - 开始搜索位置默认为数组长度         * @returns {Number}         */        lastIndexOf: function(target, start) {            var l = this.length;            if(start === void 0)                start = this.length;            else if(start < 0)                start = 0;            for(;start >= 0; --start) {                if(this[start] === target)                    return start;            }            return -1;        },        /**         * 数组去重         * @returns {Array}         */        unique: function() {            var i = 0, j,                l = this.length;            for(; i < l; ++i) {                for(j = i+1; j < l; j++) {                    if(this[i] === this[j]) {                        this.splice(j, 1);//把位置j的数组项删除                    }                }            }            return this;        },        /**         * 对于单一类型的数组,可以使用此方法去重。         * 但这类数组:[ ‘ff‘, 1, ‘1‘ ]会去重失败         * @returns {Array}         */        enhanceUnique: function() {            var ret = [], tempMap = {}, temp, i = 0, l = this.length, undef = void 0;            for(; i < l; ++i) {                temp = this[i];                if(tempMap[temp] === undef) {                    ret.push(temp);                    tempMap[temp] = true;                }            }            return ret;        },        /**         * 去掉数组中的目标元素         * @param value         * @returns {Array}         */        without: function() {            var args = [].slice.call(arguments).unique(),                i = 0, l = this.length,                j = 0, k = args.length;            for(; i < l; ++i) {                for(; j < k; ++j) {                    if(this[i] === args[j]) {                        this.splice(i, 1);                    }                }                j = 0;//将j归0,以便下次循环            }            return this;        },        /**         * 递归将数组扁平化         * @returns {Array}         */        flatten: function() {            var ret = [], i = 0, l = this.length, tmp, toString = ({}).toString;            for(; i < l; ++i) {                tmp = this[i];                if(toString.call(tmp) === ‘[object Array]‘) {                    ret = ret.concat(tmp.flatten());                } else {                    ret.push(tmp);                }            }            return ret;        },        /**         * 随机返回数组的一项         * @returns {*}         */        random: function(n) {            //Math.floor():向下取整。Math.floor(1.8) -> 1            //Math.ceil():向上取整。Math.ceil(1.1) -> 2            //v = Math.random() * n:会产生一个 0 < v < nv的数            //v2 = Math.floor(Math.random() * n):v2为一个大于等于0,小于n的整数            return this[Math.floor(Math.random() * n || this.length)];        },        /**         * 删除数组指定位置的项         * @returns {Array}         */        removeAt: function(pos) {            this.splice(pos, 1);            return this;        },        /**         * 检测数组是否包含目标值         * @returns {Boolean}         */        contains: function(target) {            return this.some(function(e, i, self) {                return e === target;            });        },        //数组的交,并,差集        /**         * 返回数组与目标数组的交集组成的数组         * @returns {Array || null}         */        intersect: function(target) {            var originalArr = this.unique(),                target = target.unique();            return originalArr.filter(function(e, i, self) {                for( var i = 0, l = target.length; i < l; ++i) {                    if(e === target[i]) {                        return true;                    }                }                return false;            });        },        /**         * 返回数组与目标数组的并集组成的数组         * @returns {Array || null}         */        union: function(target) {            return this.concat(target).unique();        },        /**         * 返回数组与目标数组的差集组成的数组         * @returns {Array || null}         */        diff: function(target) {            var originalArr = this.unique(),                target = target.unique();            return originalArr.filter(function(e, i, self) {                for( var i = 0, l = target.length; i < l; ++i) {                    if(e === target[i]) {                        return false;                    }                }                return true;            });        },        /**         * 将数组清空,并返回这个数组的引用         * @returns {Array}         */        clear: function() {            this.length = 0;            return this;        },        clone: function() {            return [].concat(this);        },        /**         * 去掉数组中的undefined, null         * @returns {Array}         */        compact: function() {            for(var i = 0, l = this.length; i < l; i++) {                if(this[i] == null)                    //删除这个位置的元素                    this.splice(i, 1);            }            return this;        },        /**         * 返回数组第一项         * @returns {*}         */        first: function() {            return this[0];        },        /**         * 返回数组最后一项         * @returns {*}         */        last: function() {            return this[this.length - 1];        },        /**         * 返回数组的大小,即数组长度         * @returns {Number}         */        size: function() {            return this.length;        }    };    for(method in arrayExtends) {        arrayExtends.hasOwnProperty(method) &&        typeof Array.prototype[method] !== ‘function‘ &&        (Array.prototype[method] = arrayExtends[method]);    }})();

 

3. 函数扩展

;(function() {    var method, functionExtends = {        /**         * 会返回一个函数:         * 1. 这个函数被设置了作用域,即this值         * 2. 如果运行bind()时有传除this外的其它参数,则此函数还会包含这些参数。         * 这些参数会与bind()返回的函数在运行时传进来的参数共同组成返回函数的参数         * @param {*} oThis - 要给函数绑定的作用域         * @returns {Function}         */        bind: function(oThis) {            var _slice = [].slice,                args = _slice.call(arguments, 1),//运行bind()方法时要闭包保存的参数                method = this;//要实际运行的函数            return function() {                return method.apply(oThis, args.concat(_slice.call(arguments)));            }        },        /**         * 函数curry是参数的一种处理,它可以更加灵活地控制参数。         * 关键点是什么时候返回函数继续增加参数,什么时候要执行函数返回结果。         * 要解决上面的问题可以在curry时引入一个变量,手动设置最少需要的参数个数。         * @param {Number} [minArgsNumber = 0] - 默认不需要任何参数         * @returns {*}         */        curry: function(minArgsNumber) {            var _slice = [].slice,                closureArgs = _slice.call(arguments, 1),                method = this,                totalArgs;            //minArgsNumber = arguments.length ? arguments[0] : 0;            minArgsNumber = typeof minArgsNumber === ‘number‘ ? minArgsNumber : 0;            return function inner() {                //到底是执行函数,还是继续等待传参由minArgsNumber决定                totalArgs = typeof totalArgs === ‘undefined‘ ?                    closureArgs.concat(_slice.call(arguments)) :                    totalArgs.concat(_slice.call(arguments));                if(totalArgs.length >= minArgsNumber) {                    //执行函数                    return method.apply(this, totalArgs);                } else {                    //继续返回函数接收参数                    return inner;                }            }        },        /**         * 以数组的形式返回函数的参数名字字符串。没有参数时返回空数组         * @returns {Array}         */        argumentNames: function() {            var ret,                methodCode = this.toString();                methodCode.replace(/\((.*?)\)//*gm 函数里面的代码也可能会有(abc)字符串*/, function(match, g1) {                    var argStr = g1.replace(/\s/g, ‘‘);                    ret = argStr.length ? argStr.split(‘,‘) : [];                });            return ret;        },        /**         * setTimeout的偷懒写法         */        delay: function(delay) {            var _slice = [].slice,                method = this,                closureArgs = _slice.call(arguments, 1);            setTimeout(function() {                method.apply(this, closureArgs.concat(_slice.call(arguments)));            }, delay);        }    };    for(method in functionExtends) {        functionExtends.hasOwnProperty(method) &&        typeof Function.prototype[method] !== ‘function‘ &&        (Function.prototype[method] = functionExtends[method]);    }})();

 

写在最后:里面有许多方法和思路都来至网上或《JavaScript框架设计》,都在此表示感谢。