不一样的javascript —— 常用的方法封装

1. 防抖

/**
 * 防抖原理:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数
 * 
 * @param {Function} func 要执行的回调函数 
 * @param {Number} wait 延时的时间
 * @param {Boolean} immediate 是否立即执行 
 * @return null
 */
let timeout = null;
export const debounce = function(func, wait = 500, immediate = false) {
	// 清除定时器
	if (timeout !== null) clearTimeout(timeout);
	// 立即执行,此类情况一般用不到
	if (immediate) {
		var callNow = !timeout;
		timeout = setTimeout(function() {
			timeout = null;
		}, wait);
		if (callNow) typeof func === 'function' && func();
	} else {
		// 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法
		timeout = setTimeout(function() {
			typeof func === 'function' && func();
		}, wait);
	}
}

2. 节流

/**
 * 节流原理:在一定时间内,只能触发一次
 * 
 * @param {Function} func 要执行的回调函数 
 * @param {Number} wait 延时的时间
 * @param {Boolean} immediate 是否立即执行
 * @return null
 */
 let timer;
 let flag;
 export const throttle = function(func, wait = 500, immediate = true) {
	if (immediate) {
		if (!flag) {
			flag = true;
			// 如果是立即执行,则在wait毫秒内开始时执行
			typeof func === 'function' && func();
			timer = setTimeout(() => {
				flag = false;
			}, wait);
		}
	} else {
		if (!flag) {
			flag = true
			// 如果是非立即执行,则在wait毫秒内的结束处执行
			timer = setTimeout(() => {
				flag = false
				typeof func === 'function' && func();
			}, wait);
		}
		
	}
};

3. 深度克隆(深拷贝)

// 判断arr是否为一个数组,返回一个bool值
function isArray(arr) {
	return Object.prototype.toString.call(arr) === '[object Array]';
}
// 主要方法
export const deepClone = function(obj) {
	if([null, undefined, NaN, false].includes(obj)) {
		return obj;
	}
    if(typeof obj !== "object" && typeof obj !== 'function') {
        return obj;
    }
    var o = isArray(obj) ? [] : {};
    for(let i in obj) {
        if(obj.hasOwnProperty(i)){
            o[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i];
        }
    }
    return o;
}

4. 对象深度合并

export const deepMerge = function(target = {}, source = {}) {
	target = deepClone(target); // 深拷贝,在上面
	if (typeof target !== 'object' || typeof source !== 'object') return false;
	for (var prop in source) {
		if (!source.hasOwnProperty(prop)) continue;
		if (prop in target) {
			if (typeof target[prop] !== 'object') {
				target[prop] = source[prop];
			} else {
				if (typeof source[prop] !== 'object') {
					target[prop] = source[prop];
				} else {
					if (target[prop].concat && source[prop].concat) {
						target[prop] = target[prop].concat(source[prop]);
					} else {
						target[prop] = deepMerge(target[prop], source[prop]);
					}
				}
			}
		} else {
			target[prop] = source[prop];
		}
	}
	return target;
}

5. 对象转url参数

/**
 * 对象转url参数
 * @param {*} data,对象
 * @param {*} isPrefix,是否自动加上"?"
 */
export const queryParams = function(data = {}, isPrefix = true, arrayFormat = 'brackets') {
	let prefix = isPrefix ? '?' : ''
	let _result = []
	if (['indices', 'brackets', 'repeat', 'comma'].indexOf(arrayFormat) == -1) arrayFormat = 'brackets';
	for (let key in data) {
		let value = data[key]
		// 去掉为空的参数
		if (['', undefined, null].indexOf(value) >= 0) {
			continue;
		}
		// 如果值为数组,另行处理
		if (value.constructor === Array) {
			// e.g. {ids: [1, 2, 3]}
			switch (arrayFormat) {
				case 'indices':
					// 结果: ids[0]=1&ids[1]=2&ids[2]=3
					for (let i = 0; i < value.length; i++) {
						_result.push(key + '[' + i + ']=' + value[i])
					}
					break;
				case 'brackets':
					// 结果: ids[]=1&ids[]=2&ids[]=3
					value.forEach(_value => {
						_result.push(key + '[]=' + _value)
					})
					break;
				case 'repeat':
					// 结果: ids=1&ids=2&ids=3
					value.forEach(_value => {
						_result.push(key + '=' + _value)
					})
					break;
				case 'comma':
					// 结果: ids=1,2,3
					let commaStr = "";
					value.forEach(_value => {
						commaStr += (commaStr ? "," : "") + _value;
					})
					_result.push(key + '=' + commaStr)
					break;
				default:
					value.forEach(_value => {
						_result.push(key + '[]=' + _value)
					})
			}
		} else {
			_result.push(key + '=' + value)
		}
	}
	return _result.length ? prefix + _result.join('&') : ''
}

6. 获取两个数之间的随机数

/**
 * 获取两个数之间的随机数
 * @param {*} min,最小数
 * @param {*} max,最大数
 */
export const random = function(min, max) {
	if (min >= 0 && max > 0 && max >= min) {
		let gab = max - min + 1;
		return Math.floor(Math.random() * gab + min);
	} else {
		return 0;
	}
}

7. 打乱数组

/**
 * 打乱数组
 * @param {*} arr,需要打乱的数组
 */
export const randomArray = function(array = []) {
	return array.sort(() => Math.random() - 0.5);
}

8. 时间格式化

/**
 * 时间格式化
 * @param {*} dateTime,秒、毫秒
 * @param {*} fmt,格式
 * yyyy:mm:dd | yyyy:mm | yyyy年mm月dd日 | yyyy年mm月dd日 hh时MM分...
 */
 export const timeFormat = function(dateTime = null, fmt = 'yyyy-mm-dd') {
	// 如果dateTime为null,则格式化当前时间
	if (!dateTime) {
		dateTime = Number(new Date());
	}
	// 如果dateTime长度为10或者13,则为秒和毫秒的时间戳,如果超过13位,则为其他的时间格式
	if (dateTime.toString().length == 10) {
		dateTime *= 1000;
	}
	let date = new Date(dateTime);
	let ret;
	let 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) {
			// padStart() 方法用另一个字符串填充当前字符串(如果需要的话,会重复多次),以便产生的字符串达到给定的长度。从当前字符串的左侧开始填充
			fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
		};
	};
	return fmt;
}

9. 字符串去除空格

/**
 * 字符串去除空格
 * @param {*} str,字符串
 * @param {*} pos,清楚什么部位的空格 
 * 
 * both  	默认值,去除两端空格,
 * left		去除左边空格,
 * right	去除右边空格,
 * all		去除包括中间和两端的所有空格
 */
 export const trim = function(str, pos = 'both') {
	if (pos == 'both') {
		return str.replace(/^\s+|\s+$/g, "");
	} else if (pos == "left") {
		return str.replace(/^\s*/, '');
	} else if (pos == 'right') {
		return str.replace(/(\s*$)/g, "");
	} else if (pos == 'all') {
		return str.replace(/\s+/g, "");
	} else {
		return str;
	}
}

10. 一维数组转二维数组

/**
 * @description 一维数组转二维数组
 * @param arr 要转化的一维数组
 * @param num
 */
export const arrOneChangeTwo = function(arr, num) {
	if(!Array.isArray(arr)) {
		return [];
	}
	if(Array.isArray(arr) && arr.length <= 1) {
		return arr;
	}
	let a = [];
	while(arr.length > 0) {
		a.push(arr.splice(0, num))
	}
	return a;
}

11. 二维数组转一维数组

/**
 * @description 二维数组转一维数组
 * @param 
 * @param 
 */
export const arrTwoChangeOne = function(arr) {
	if(!Array.isArray(arr)) { 
		return [];
	}
	return [].concat.apply([], arr)
}

12. 深度克隆多维数组

/**
 * @description 深度克隆多维数组
 * @param {Array} arr 需要深度克隆的数组
 * @returns {*} 克隆后的数组
 */
export const deepcopyArray = function(arr) {
	let out = [];
	let i = 0;
	let len = arr.length;
	for (; i < len; i++) {
		if (arr[i] instanceof Array){
			out[i] = deepcopyArray(arr[i]);
		}
		else out[i] = arr[i];
	}
	return out;
}

13. 未完待续…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张_大_炮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值