1.生成唯一uuid
根据自己项目需求,生成对应的唯一uuid
UUIDGenerator: () => {
function S4 () {
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
}
return (
S4() +
S4() +
'-' +
S4() +
'-' +
S4() +
'-' +
S4() +
'-' +
S4() +
S4() +
S4()
)
},
js数据类型检测方法
// 类型检测方法
const toType = function toType(obj) {
const reg = /^\[object ([\w\W]+)\]$/;
if (obj === null) return obj + "";
// const isObj = typeof obj === 'object' || typeof obj === 'function';
const isObj = /^(object|fuction)$/.test(typeof obj),
getObjClass = Object.prototype.toString;
// reg.exec(getObjClass.call(obj)) 返回的是一个数组,数组第二项[1]表示 第一个括号内的匹配结果
return isObj ? reg.exec(getObjClass.call(obj))[1].toLowerCase(): typeof obj
}
function 函数检测方法
const isFunction = function isFunction(obj) {
return typeof obj === 'function' && typeof obj.nodeType !=='number' && typeof obj.item !=='function'
}
window对象检测
const isWindow = function isWindow(obj) {
return obj != null && obj === obj.window;
};
类数组检测
const isArrayLike = function isArrayLike(obj) {
// 若为假值即 null, undefined,false, 空字符串(""),或数字0,
// !! (取反再取反)用来快速地将一个可能为假值的变量转换为布尔值
let length = !!obj && "length" in obj && obj.length,
type = toType(obj); // 上述封装的函数
if (isFunction(obj) || isWindow(obj)) return false;
return type === 'array' || length === 0 || typeof length === 'number' && length > 0 && (length - 1) in obj;
}
标准普通对象
// 标准普通对象
const isPlainObject = function isPlainObject(obj) {
let proto, Ctor;
if (!obj || Object.prototype.toString.call(obj) !== "[object object]") return false;
proto = Object.getPrototypeOf(obj); // 获取指定对象的原型
if (!proto) return true; // 匹配 Object.create(null) 创建一个没有原型对象的对象
Ctor = Object.prototype.hasOwnProperty.call(proto, 'constructor') && proto.constructor;
return typeof Ctor === 'function' && Ctor === Object;
}
数组对象遍历
const each = function each(obj, callback) {
let isArray = isArrayLike(obj),
isObject = isPlainObject(obj);
if (!isArray && !isObject) throw new TypeError('obj must be a array or likeArray or plainObject');
if (!isFunction(callback)) throw new TypeError('callback is not a function');
if (isArray) {
for (let i = 0; i < obj.length; i++) {
let item = obj[i],
index = i;
if (callback.call(item, item, index) === false) break;
}
return obj;
}
let keys = Object.getOwnPropertyNames(obj);
if (typeof Symbol !== "undefined") keys = keys.concat(Object.getOwnPropertySymbols(obj));
for (let i = 0; i < keys.length; i++) {
let key = keys[i],
value = obj[key];
if (callback.call(value, value, key) === false) break;
}
return obj;
};
常用工具代码集合
(function () {
/* 检测数据类型 */
const class2type = {},
toString = class2type.toString,
hasOwn = class2type.hasOwnProperty;
const toType = function toType(obj) {
let reg = /^\[object ([\w\W]+)\]$/;
if (obj == null) return obj + "";
return typeof obj === "object" || typeof obj === "function" ?
reg.exec(toString.call(obj))[1].toLowerCase() :
typeof obj;
};
const isFunction = function isFunction(obj) {
return typeof obj === "function" &&
typeof obj.nodeType !== "number" &&
typeof obj.item !== "function";
};
const isWindow = function isWindow(obj) {
return obj != null && obj === obj.window;
};
const isArrayLike = function isArrayLike(obj) {
// 若为假值既null、undefined、false、空字符串("")或数字0,
// 用来快速地将一个可能为假值的变量转换为布尔值
let length = !!obj && "length" in obj && obj.length,
type = toType(obj);
if (isFunction(obj) || isWindow(obj)) return false;
return type === "array" || length === 0 ||
typeof length === "number" && length > 0 && (length - 1) in obj;
};
const isPlainObject = function isPlainObject(obj) {
let proto, Ctor;
if (!obj || toString.call(obj) !== "[object Object]") return false;
proto = Object.getPrototypeOf(obj);
if (!proto) return true; //匹配 Object.create(null)
Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
return typeof Ctor === "function" && Ctor === Object;
};
const isEmptyObject = function isEmptyObject(obj) {
let keys = Object.getOwnPropertyNames(obj);
if (typeof Symbol !== "undefined") keys = keys.concat(Object.getOwnPropertySymbols(obj));
return keys.length === 0;
};
const isNumeric = function isNumeric(obj) {
var type = toType(obj);
return (type === "number" || type === "string") &&
!isNaN(obj - parseFloat(obj));
};
/* 函数的防抖和节流 */
const clearTimer = function clearTimer(timer) {
if (timer) clearTimeout(timer);
return null;
};
const debounce = function debounce(func, wait, immediate) {
if (typeof func !== "function") throw new TypeError("func is not a function!");
if (typeof wait === "boolean") {
immediate = wait;
wait = undefined;
}
wait = +wait;
if (isNaN(wait)) wait = 300;
if (typeof immediate !== "boolean") immediate = false;
let timer = null;
return function operate(...params) {
let now = !timer && immediate;
timer = clearTimer(timer);
timer = setTimeout(() => {
if (!immediate) func.call(this, ...params);
timer = clearTimer(timer);
}, wait);
if (now) func.call(this, ...params);
};
};
const throttle = function throttle(func, wait) {
if (typeof func !== "function") throw new TypeError("func is not a function!");
wait = +wait;
if (isNaN(wait)) wait = 300;
let timer = null,
previous = 0;
return function operate(...params) {
let now = +new Date(),
remaining = wait - (now - previous);
if (remaining <= 0) {
func.call(this, ...params);
previous = +new Date();
timer = clearTimer(timer);
} else if (!timer) {
timer = setTimeout(() => {
func.call(this, ...params);
previous = +new Date();
timer = clearTimer(timer);
}, remaining);
}
};
};
/* 数组和对象的操作 */
const mergeArray = function mergeArray(first, second) {
if (typeof first === "string") first = Object(first);
if (typeof second === "string") second = Object(second);
if (!isArrayLike(first)) first = [];
if (!isArrayLike(second)) second = [];
let len = +second.length,
j = 0,
i = first.length;
for (; j < len; j++) {
first[i++] = second[j];
}
first.length = i;
return first;
};
const each = function each(obj, callback) {
let isArray = isArrayLike(obj),
isObject = isPlainObject(obj);
if (!isArray && !isObject) throw new TypeError('obj must be a array or likeArray or plainObject');
if (!isFunction(callback)) throw new TypeError('callback is not a function');
if (isArray) {
for (let i = 0; i < obj.length; i++) {
let item = obj[i],
index = i;
if (callback.call(item, item, index) === false) break;
}
return obj;
}
let keys = Object.getOwnPropertyNames(obj);
if (typeof Symbol !== "undefined") keys = keys.concat(Object.getOwnPropertySymbols(obj));
for (let i = 0; i < keys.length; i++) {
let key = keys[i],
value = obj[key];
if (callback.call(value, value, key) === false) break;
}
return obj;
};
// 实现数组&对象的“深浅”合并
const merge = function merge(...params) {
// target被替换项 options替换项 treated是一个Set集合,用来记录哪些对象已经处理过了
let options,
target = params[0],
i = 1,
length = params.length,
deep = false,
treated = params[length - 1];
// 最开始没有treated或者递归的时候有了
toType(treated) === 'set' ? length-- : treated = new Set();
/*
if(toType(treated) === 'set' && treated.isHandler){
// 递归执行merge 的时候
length--;
}else {
// 第一次执行merge
treated = new Set();
treated.isHandler = true;
}
*/
// 第一项是布尔值:传递给deep控制深浅合并的
if (typeof target === "boolean") {
deep = target;
target = params[i];
i++;
}
// 必须保证被替换项是一个对象
if (target == null || (typeof target !== "object" && !isFunction(target))) target = {};
// 迭代传递的剩下的对象,依次替换target
for (; i < length; i++) {
// 获取某一替换项
options = params[i];
if (options == null) continue;
// 防止死递归的处理
if (treated.has(options)) return options;
treated.add(options);
// 依次拿出“替换项”中每一项,替换“被替换项”中同名这一项
// copy->value, name-> key
each(options, (copy, name) => {
let copyIsArray = Array.isArray(copy),
copyIsObject = isPlainObject(copy),
src = target[name]; // 被替换中的那一项值
// copy -> 替换中的项 src-> 被替换中的值
if (deep && copy && (copyIsArray || copyIsObject)) {
// 深合并
if (copyIsArray && !Array.isArray(src)) src = [];
if (copyIsObject && !isPlainObject(src)) src = {};
target[name] = merge(deep, src, copy, treated);
} else if (copy !== undefined) {
// 浅合并
target[name] = copy;
}
});
}
// 返回被替换这一项
return target;
};
// 实现数组&对象的“深浅”拷贝
const clone = function clone(...params) {
// target被拷贝的值 deep深浅拷贝
let target = params[0],
deep = false,
length = params.length,
i = 1,
type,
isArray,
isObject,
result,
treated;
if (typeof target === "boolean" && length > 1) {
deep = target;
target = params[1];
i = 2;
}
// 防止死递归
treated = params[i];
if (!treated) treated = new Set();
if (treated.has(target)) return target;
treated.add(target);
type = toType(target);
isArray = Array.isArray(target);
isObject = isPlainObject(target);
// 特殊值的拷贝「函数无需拷贝」
if (target == null) return target;
if (!isArray && !isObject && !isFunction(target) && typeof target === "object") {
// 非标准特殊对象,标准特殊对象
try {
// 实例的constructor,所属类原型上的constructor,当前构造函数本身
return new target.constructor(target);
} catch (_) {
return target;
}
}
if (!isArray && !isObject) return target;
// 数组和纯粹对象
result = new target.constructor();
each(target, (copy, name) => {
if (deep) {
// 深拷贝
result[name] = clone(deep, copy, treated);
return;
}
// 浅拷贝
result[name] = copy;
});
return result;
};
const utils = {
toType,
isFunction,
isWindow,
isArrayLike,
isPlainObject,
isEmptyObject,
isNumeric,
debounce,
throttle,
mergeArray,
each,
merge,
clone
};
/* 处理冲突 */
if (typeof window !== "undefined") {
let $ = window._;
utils.noConflict = function noConflict() {
if (window._ === utils) {
window._ = $;
}
return utils;
};
}
/* 导出API */
if (typeof window !== "undefined") window.utils = window._ = utils;
if (typeof module === "object" && typeof module.exports === "object") module.exports = utils;
})();