前端utils工具集锦

127 阅读2分钟

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;
})();