JavaScript 常用函数

87 阅读3分钟
工作多年,很多项目都用得上的函数,总结一下,持续更新中……
  • 富文本HTML解析
function htmlspecialcharsDecode(str){
        if(!str || str === '') return '';
        const maxPx = 750;
        // 解析富文本
        let targats = [
                [/&/g ,							'&' ],
                [/&lt;/g ,							'<' ],
                [/&gt;/g ,							'>' ],
                [/&quot;/g ,						"'" ],
                [/&#039;/g ,						"'" ],
                [/<!--.*?-->/g ,					''  ],
                [/750px/gi ,			  	`${maxPx}px`],
                [/nowrap/g ,				   'normal'	],
                [/<a/g ,				  		'<span' ],
                [/<\/a/g ,					   '</span' ],
                [/&#xe61d;/g ,						 '' ],
                [/width=('|").*?('|")/g ,			 '' ],
                [/height=('|").*?('|")/g ,		     '' ],
                [/<video/g,						`<video style="width:${maxPx}px !important; height:auto; background-color:#000000;"`	],
                [/<img/g ,						`<img style="width:100% !important; height:auto;display:block;margin:${bpx}px auto;"` 	],
                [/<p/g,	 						`<p style="padding:${bpx}px 0;"` ],
                [/src=('|")\/Upload\//g,		`src="${this.$baseUrl}/Upload/`  ]
        ]
        for(const key in targats){
                str = str.replace(targats[key][0],targats[key][1]);
        }
        return str;
}
  • 数字显示千,万……
numberFormat(num){
        num = Number(num);
        let format = '';
        switch(true){
                case num >= 100000000:
                        format = `${(num / 100000000).toFixed(1)}亿`;
                        break;
                case num >= 10000000:
                        format = `${(num / 10000000).toFixed(1)}千万`;
                        break;
                case num >= 1000000:
                        format = `${(num / 1000000).toFixed(1)}百万`;
                        break;
                case num >= 10000:
                        format = `${(num / 10000).toFixed(1)}万`;
                        break;
                case num >= 1000:
                        format = `${(num / 1000).toFixed(1)}千`;
                        break;
                default:
                        format = num;
                        break;
        }
        return format;
}
  • 休眠
sleep(delay){
        return new Promise((resolve)=>setTimeout(resolve,delay));
}
  • 深拷贝
cloneDeep(value) {

        // 记录被拷贝的值,避免循环引用的出现
        let memo = {};
        /**
         * 判断是否是基本数据类型
         * @param value 
         */
        function isPrimitive(value) {
                return (typeof value === 'string' ||
                        typeof value === 'number' ||
                        typeof value === 'symbol' ||
                        typeof value === 'boolean')
        }

        /**
         * 判断是否是一个js对象
         * @param value 
         */
        function isObject(value) {
                return Object.prototype.toString.call(value) === "[object Object]"
        }

        function baseClone(value) {
                let res;
                // 如果是基本数据类型,则直接返回
                if (isPrimitive(value)) {
                        return value;
                        // 如果是引用数据类型,我们浅拷贝一个新值来代替原来的值
                } else if (Array.isArray(value)) {
                        res = [...value];
                } else if (isObject(value)) {
                        res = {
                                ...value
                        };
                }

                // 检测我们浅拷贝的这个对象的属性值有没有是引用数据类型。如果是,则递归拷贝
                Reflect.ownKeys(res).forEach(key => {
                        if (typeof res[key] === "object" && res[key] !== null) {
                                //此处我们用memo来记录已经被拷贝过的引用地址。以此来解决循环引用的问题
                                if (memo[res[key]]) {
                                        res[key] = memo[res[key]];
                                } else {
                                        memo[res[key]] = res[key];
                                        res[key] = baseClone(res[key])
                                }
                        }
                })
                return res;
        }

        return baseClone(value)
}
  • 根据经纬度计算距离
getDistance(start, end) {
        let slat = Number(start.latitude);
        let slon = Number(start.longitude);
        let elat = Number(end.latitude);
        let elon = Number(end.longitude);
        // console.log('计算地点经纬度:', lat1, lng1);
        let rad1 = elat * Math.PI / 180.0;
        let rad2 = slat * Math.PI / 180.0;
        let a = rad1 - rad2;
        let b = elon * Math.PI / 180.0 - slon * Math.PI / 180.0;
        let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(rad1) * Math.cos(
                rad2) * Math.pow(
                Math.sin(b / 2), 2)));
        s = s * 6378.137;
        s = Math.round(s * 10000) / 10000;
        s = s.toString();
        s = s.substring(0, s.indexOf('.') + 2);
        return s; //返回距离
}
  • 时间格式化
dateFormat(date,fmt = 'YYYY-mm-dd HH:MM'){
        let ret;
        const opt = {
            "Y+": date.getFullYear().toString(),        // 年
            "m+": (date.getMonth() + 1).toString(),     // 月
            "d+": date.getDate().toString(),            // 日
            "H+": date.getHours().toString(),           // 时
            "M+": date.getMinutes().toString(),         // 分
            "S+": date.getSeconds().toString()          // 秒
            // 有其他格式化字符需求可以继续添加,必须转化成字符串
        };
        for (let k in opt) {
            ret = new RegExp("(" + k + ")").exec(fmt);
            if (ret) {
                fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
            };
        };
        return fmt;
}
  • 一维数组转二维数组
/**
 * 分割数组创建二维数组封装
 * @param data 数组
 * @param senArrLen 需要分割成子数组的长度
 */
function splitArr(data, senArrLen = 5) {
	//处理成len个一组的数据
	let data_len = data.length;
	let arrOuter_len = data_len % senArrLen === 0 ? data_len / senArrLen : parseInt((data_len /
		senArrLen) + '') + 1;
	let arrSec_len = data_len > senArrLen ? senArrLen : data_len; //内层数组的长度
	let arrOuter = new Array(arrOuter_len); //最外层数组
	let arrOuter_index = 0; //外层数组的子元素下标
	// console.log(data_len % len);
	for (let i = 0; i < data_len; i++) {
		if (i % senArrLen === 0) {
			arrOuter_index++;
			let len = arrSec_len * arrOuter_index;
			//将内层数组的长度最小取决于数据长度对len取余,平时最内层由下面赋值决定
			arrOuter[arrOuter_index - 1] = new Array(data_len % senArrLen);
			if (arrOuter_index === arrOuter_len) //最后一组
				data_len % senArrLen === 0 ?
				len = data_len % senArrLen + senArrLen * arrOuter_index :
				len = data_len % senArrLen + senArrLen * (arrOuter_index - 1);
			let arrSec_index = 0; //第二层数组的索引
			for (let k = i; k < len; k++) { //第一层数组的开始取决于第二层数组长度*当前第一层的索引
				arrOuter[arrOuter_index - 1][arrSec_index] = data[k];
				arrSec_index++;
			}
		}
	}
	return arrOuter
}
  • 倒计时
function countDown(start_stamp) {
	if (!start_stamp) return {
		day: '00',
		hours: '00',
		minutes: '00',
		seconds: '00',
		hasSeckill: false
	}
	let end_time = new Date(Number(start_stamp) * 1000).getTime()
	let now_time = new Date().getTime()
	let time = Math.round((end_time - now_time) / 1000)
	if(time <= 0) return {
		day: '00',
		hours: '00',
		minutes: '00',
		seconds: '00',
		hasSeckill: false
	}
	// console.log(start_stamp)
	let d = parseInt(time / 60 / 60 / 24)
	let h = parseInt(((time / 60 / 60) % 24) + (d * 24))
	let m = parseInt((time / 60) % 60)
	let s = parseInt(time % 60)
	return {
		day: d.toString().padStart(2, '0'),
		hours: h.toString().padStart(2, '0'),
		minutes: m.toString().padStart(2, '0'),
		seconds: s.toString().padStart(2, '0'),
		hasSeckill: true
	}
}
  • 还有很多没整理,有错误或者补充可以在评论区留言哈