JS项目中常用方法总结

277 阅读2分钟
/**
 * @description: JS 常用方法封装
 * @param {*} checkDataType         数据类型检查
 * @param {*} randomNum             生成随机数,支持随机小数
 * @param {*} easyArrRepetition     简单数组去重
 * @param {*} complexArrRepetition  复杂数组去重
 * @param {*} promiseAll            封装 Promise.all 遇到 reject 后,直接返回问题
 * @param {*} dateFormat            秒级时间戳、毫秒级时间戳、日期对象 格式化时间
 * @param {*} checkMobile           验证手机号格式是否正确
 * @param {*} checkEmail            验证邮箱格式是否正确
 * @param {*} checkPassword         验证密码格式是否正确 (必须为 6-20 个字符,而且同时包含字母和数字)
 * @param {*} createRandomNum       生成n位随机数
 * @param {*} toDecimal2            保留2位小数
 * @param {*} createUuid            生成uuid
 * @param {*} browserInfo           判断运行环境
 * @param {*} detectOS              判断运行设备
 * @param {*} throttle              节流(throttle)
 * @param {*} debounce              防抖(debounce)
 * @param {*} ThousandNum           格式化金钱
 * @param {*} RandomId              生成随机ID
 * @param {*} RandomColor           生成随机HEX色值
 * @param {*} lazyLoad              懒加载
 * @param {*} loadMore              加载更多
 * @param {*} fixedToHeader         固定到顶部(吸顶)
 * @param {*} strToJson         JSON.parse解析报错处理方案
 */
数据类型检查
/**
 * @description: JS 数据类型检查
 * @param {*} content   检测值
 * @param {*} Type      期待类型
 * @return {*} Boolean
 */
export function checkDataType(content, Type) {
    return Object.prototype.toString.call(content) === `[object ${Type}]`;
}
checkDataType('hello','string') //true
生成随机数,支持随机小数
/**
 * @description: 生成随机数,支持随机小数
 * @param {*} min   最小值
 * @param {*} max   最大值
 * @param {*} point 几位小数,默认0
 * @return {*} String
 */
export function randomNum(min = 0, max = 100, point = 0) {
    if (point && point > 0) {
        return (Math.random() * (max - min + 1) + min).toFixed(point);
    }
    return parseInt(Math.random() * (max - min + 1) + min);
}
randomNum(10,30,2) //20.75
简单数组去重
/**
 * @description 简单数组去重
 * @param {*} arg  数组
 * @returns Array
 */
export function easyArrRepetition(...arg) {
    return [...new Set([...arg].flat(Infinity))];
}
const arr1 = [1,2,3],arr2 = [2,3,4]
easyArrRepetition(arr1, arr2) //[ 1, 2, 3, 4 ]
复杂数组去重
/**
 * @description 复杂数组去重
 * @param key 根据key进行去重
 * @param arg 数组
 * @returns Array
 */
export function complexArrRepetition(key, ...arg) {
    if (!key || typeof key !== "string") return new Error("请传入正确的key值");
    let arr = [...arg].flat(Infinity);
    let hash = {};
    return arr.reduce((next, item) => {
        hash[item[key]] ? "" : (hash[item[key]] = true && next.push(item));
        return next;
    }, []);
}
const arr1 = [
    { name: '张三', id: 1 },
    { name: '李四', id: 2 },
    { name: '王五', id: 3 }
]
const arr2 = [
    { name: '张三', id: 1 },
    { name: '李四', id: 2 },
    { name: '赵六', id: 5 }
]
complexArrRepetition('id', arr1, arr2) 
/*
    [
      { name: '张三', id: 1 },
      { name: '李四', id: 2 },
      { name: '王五', id: 3 },
      { name: '赵六', id: 5 }
    ]
*/
封装 Promise.all 遇到 reject 后,直接返回问题
/**
 * @description 封装 Promise.all 遇到 reject 后,直接返回问题
 * @param arg promise数组
 * @returns Promise
 */
export function promiseAll(...arg) {
    return new Promise((resolve, reject) => {
        const promiseAll = [...arg]
            .flat(Infinity)
            .map(
                (item) =>
                (Object.prototype.toString.call(item) ===
                    "[object Promise]" &&
                    item.catch((e) => e)) ||
                item
            );
        Promise.all(promiseAll)
            .then((res) => {
                resolve(res);
            })
    });
}
const promiseArr = [
    Promise.resolve('resolve'),
    Promise.reject('reject'),
    'hello word',
    { name: '张三' }
]
promiseAll(promiseArr).then(res => {
    console.log(res); 
    //[ 'resolve', 'reject', 'hello word', { name: '张三' } ]

})
秒级时间戳、毫秒级时间戳、日期对象 格式化时间
/**
 * @description 秒级时间戳、毫秒级时间戳、日期对象 格式化时间
 * @param date
 * @param fmt
 * @returns string
 */
export function dateFormat(date, fmt = "yyyy-MM-dd hh:mm:ss") {
    let type = Object.prototype.toString.call(date);
    if (type !== "[object Number]" && type !== "[object Date]") return;
    if (type === "[object Number]")
        date = new Date(
            Number(date).toString().length === 10 ? date * 1000 : date
        );
    let o = {
        "M+": date.getMonth() + 1, //月份
        "d+": date.getDate(), //日
        "h+": date.getHours(), //小时
        "m+": date.getMinutes(), //分
        "s+": date.getSeconds(), //秒
        "q+": Math.floor((date.getMonth() + 3) / 3), //季度
        S: date.getMilliseconds(), //毫秒
    };
    if (/(y+)/.test(fmt))
        fmt = fmt.replace(
            RegExp.$1,
            (date.getFullYear() + "").substr(4 - RegExp.$1.length)
        );
    for (let k in o)
        if (new RegExp("(" + k + ")").test(fmt))
            fmt = fmt.replace(
                RegExp.$1,
                RegExp.$1.length === 1 ?
                o[k] :
                ("00" + o[k]).substr(("" + o[k]).length)
            );
    return fmt;
}
dateFormat(new Date(), 'yyyy-MM-dd hh') // 2020-11-24 15
验证手机号格式是否正确
}
/**
 * @description 验证手机号格式是否正确
 * @param phone  手机号
 * @returns boolean
 */
export function checkMobile(phone) {
    let reg = /^1\d{10}$/;
    return !!reg.test(phone);
}
checkMobile(13113113133) // true
验证邮箱格式是否正确
}
/**
 * @description 验证邮箱格式是否正确
 * @param email  邮箱
 * @returns boolean
 */
export function checkEmail(email) {
    let reg = /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/;
    return !!reg.test(email);
}
checkEmail('test@163.com') //true
验证密码格式是否正确
}
/**
 * @description 验证密码格式是否正确 (必须为 6-20 个字符,而且同时包含字母和数字)
 * @param password  密码
 * @returns boolean
 */
export function checkPassword(password) {
    let reg = /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/;
    return !!reg.test(password);
}
checkPassword('test123') //true
生成n位随机数
/**
 * @description 生成n位随机
 * @param n  随机数位数
 * @returns string
 */
export function createRandomNum(n) {
    let rnd = "";
    for (let i = 0; i < n; i++) {
        rnd += Math.floor(Math.random() * 10);
    }
    return parseInt(rnd, 10);
}
createRandomNum(12) //506177665520
保留2位小数
/**
 * @description 保留2位小数
 * @param x  0.00格式
 * @returns string
 */
export function toDecimal2(x) {
    var f = parseFloat(x);
    if (isNaN(f)) {
        return false;
    }
    var f = Math.round(x * 100) / 100;
    var s = f.toString();
    var rs = s.indexOf(".");
    if (rs < 0) {
        rs = s.length;
        s += ".";
    }
    while (s.length <= rs + 2) {
        s += "0";
    }
    return s;
}
toDecimal2(138) //138.00
生成uuid
/**
 * @description 生成uuid
 * @returns string
 */
export function createUuid() {
    let d = new Date().getTime();
    let uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
        /[xy]/g,
        function(c) {
            let r = (d + Math.random() * 16) % 16 | 0;
            d = Math.floor(d / 16);
            return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
        }
    );
    return uuid;
}
createUuid() //48b4a373-8ad5-460f-ba2b-77561a43c413
判断运行环境
/**
 * @description 判断运行环境
 * @returns object
 */
export function browserInfo() {
    let ua = navigator.userAgent;
    return {
        isAndroid: Boolean(ua.match(/android/gi)),
        isIphone: Boolean(ua.match(/iphone|ipod/gi)),
        isIpad: Boolean(ua.match(/ipad/gi)),
        isWeixin: Boolean(ua.match(/MicroMessenger/gi)),
        isAli: Boolean(ua.match(/AlipayClient/gi)),
        isPhone: Boolean(/(iPhone|iPad|iPod|iOS|Android)/i.test(ua)),
        isApp: Boolean(/(zwwl-ios|zwwl-android)/i.test(ua)),
    };
}
browserInfo()
//{"isAndroid":false,"isIphone":true,"isIpad":false,"isWeixin":false,"isAli":false,"isPhone":true}

判断运行设备
/**
 * @description 判断运行设备
 * @returns string
 */
export function detectOS() {
    const { platform } = navigator;
    const isWin =
        platform.toLowerCase() == "win32" ||
        platform.toLowerCase() == "windows";
    const hasLinux = platform.toLowerCase().includes("linux");
    const hasTouch = "ontouchend" in document;
    if (isWin) return "Windows";
    if (hasLinux) return "Pad";
    if (hasTouch) {
        return "iPad";
    } else {
        return "Mac";
    }
}
detectOS() // mac
深拷贝
/**
 * @description: 深拷贝
 * @param {*} arg
 * @return {*} object
 */
export function deepClone(arg) {
    return arg && JSON.parse(JSON.stringify(arg))
}
deepClone() // object
格式化金钱
/**
 * @description: 格式化金钱
 * @param {*} num
 * @return {*}  string
 */
export function thousandNum(num) {
    const types = ["string", "number"];
    if (!types.includes(typeof num)) return new Error('传入参数格式错误!')
    return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
thousandNum(1453257.45) //1,453,257.45
生成随机ID
/**
 * @description: 生成随机ID
 * @param {*} len
 * @return {*}  string
 */
export function randomId(len = 6) {
    const types = ["string", "number"];
    if (!types.includes(typeof len)) return new Error('传入参数格式错误!')
    return Math.random().toString(36).substr(3, len);
}
randomId(8) // fxh4e43z
生成随机HEX色值
/**
 * @description: 生成随机HEX色值
 * @return {*} string
 */
export function randomColor() {
    return "#" + Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, "0");
}
randomColor() // #f313f1
懒加载
/**
 * @description: 懒加载
 * @param {*} els 元素列表
 * @param {*} preloadHeight 预加载高度
 * @param {*} defaultSrc 渲染真实url标签属性名
 * @return {*}
 */
export function lazyLoad(
	els = [],
	preloadHeight = 1000,
	defaultSrc = "data-src"
) {
	const observer = new IntersectionObserver(
		(entries) => {
			entries.forEach((entry) => {
				if (entry.isIntersecting) {
					// 目标元素出现在 root 可视区,返回 true
					const elTarget = entry.target;
					const src = elTarget.getAttribute(defaultSrc);
					src && elTarget.setAttribute("src", src); // 真正加载图片
					observer.unobserve(elTarget); // 停止观察
				}
			});
		},
		{
			rootMargin: `0px 0px ${preloadHeight}px 0px`,
			threshold: 0.1, //触发目标元素可见的时机
		}
	);
	Array.prototype.forEach.call(els, (el) => {
		observer.observe(el); // 开始观察
	});
}
加载更多
/**
 * @description: 加载更多
 * @param {*} cb 触底后的回调函数
 * @param {*} el 触底元素
 * @return {*}
 */
export function loadMore(cb, el) {
	if (!el || typeof el === "string") {
		throw new Error("请传入一个触底的dom元素");
		return;
	}
	const observer = new IntersectionObserver((entries) => {
		entries.forEach((entry) => {
			if (entry.isIntersecting) {
				cb();
			}
		});
	});
	observer.observe(el);
}
固定到顶部(吸顶)
/**
 * @description: 固定到顶部(吸顶)
 * @param {*} fixedEl 顶部固定元素
 * @param {*} observerEl 监听吸顶元素
 * @param {*} className 固定到底部的className
 * @return {*}
 */
export function fixedToHeader(fixedEl, observerEl, className) {
	const observer = new IntersectionObserver((entries) => {
		entries.forEach((entry) => {
			if (!entry.isIntersecting) {
				className
					? fixedEl.classList.add(className)
					: (fixedEl.style.cssText =
							"position: sticky; top: -1px; left: 0");
			} else {
				className
					? fixedEl.classList.remove(className)
					: (fixedEl.style.cssText = "");
			}
		});
	});
	observer.observe(observerEl);
}
JSON.parse解析报错处理方案
/**
 * @description: string to json
 * @param {*} jsonStr Json字符串
 * @return {*}
 */
export function strToJson(jsonStr) {
	let obj = {};
	if (
		jsonStr &&
		Object.prototype.toString.call(jsonStr) == "[object String]" &&
		jsonStr != "null"
	) {
		jsonStr = jsonStr.replace(/\r/g, '\\r') 
                jsonStr = jsonStr.replace(/\n/g, '\\n') 
                jsonStr = jsonStr.replace(/\t/g, '\\t') 
                jsonStr = jsonStr.replace(/\\/g, '\\\\') 
                jsonStr = jsonStr.replace(/\'/g, '&#39;') 
                jsonStr = jsonStr.replace(/ /g, '&nbsp;') 
                jsonStr = jsonStr.replace(/</g, '$lt;') 
                jsonStr = jsonStr.replace(/>/g, '$gt;')
		obj = JSON.parse(jsonStr);
	}
	return obj;
}

后续会继续在这篇文章上总结JS开发技巧....

如果觉得对你有帮助,请动用你的小手点点赞,感谢!