侧边栏壁纸
博主头像
小佑Blog| 小佑前端 | WEB前端博客 | WEB前端笔记 博主等级

未来属于那些相信梦想,并愿意为之付诸行动的人

  • 累计撰写 69 篇文章
  • 累计创建 92 个标签
  • 累计收到 67 条评论

目 录CONTENT

文章目录

Js封装utils库

@小佑前端
2020-11-28 / 0 评论 / 0 点赞 / 659 阅读 / 0 字 / 正在检测是否收录...
(function () {
    "use strict";
    var getProto = Object.getPrototypeOf,
        class2type = {},
        toString = class2type.toString,
        hasOwn = class2type.hasOwnProperty,
        fnToString = hasOwn.toString,
        ObjectFunctionString = fnToString.call(Object);

    ### 专门进行数据类型检测的办法 
    var toType = function toType(obj) {
        if (obj == null) return obj + "";
        if (typeof obj !== "object" && typeof obj !== "function") return typeof obj;
        var reg = /^\[object ([0-9A-Za-z]+)\]$/,
            value = reg.exec(toString.call(obj))[1] || "object";
        return value.toLowerCase();
    };

    // 检测是否为一个函数
    var isFunction = function isFunction(obj) {
        return typeof obj === "function" && typeof obj.nodeType !== "number";
    };

    // 检测是否为一个window对象
    var isWindow = function isWindow(obj) {
        return obj != null && obj === obj.window;
    };

    // 检测是否为数组或者类数组
    var isArrayLike = function isArrayLike(obj) {
        var 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;
    };

    ### 检测是否为纯粹的对象:直属类是Object 或者 obj.__proto__===Object.prototype(数组/正则等都不是)
    var isPlainObject = function isPlainObject(obj) {
        var proto, Ctor;
        if (!obj || toType(obj) !== "object") return false;
        proto = getProto(obj);
        if (!proto) return true;
        Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
        return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;
    };

    // 检测是否为空对象
    var isEmptyObject = function isEmptyObject(obj) {
        if (obj == null) return false;
        var keys = Object.keys(obj);
        if (typeof Symbol !== "undefined") {
            keys = keys.concat(Object.getOwnPropertySymbols(obj));
        }
        return keys.length === 0;
    };

    ### 检测是否为数字
    var isNumeric = function isNumeric(obj) {
        var type = toType(obj);
        return (type === "number" || type === "string") && !isNaN(+obj);
    };

    ### 函数防抖
    var debounce = function debounce(func, wait, immediate) {
        if (typeof func !== "function") throw new TypeError('func must be required and be an function!');
        if (typeof wait === "boolean") {
            immediate = wait;
            wait = 300;
        }
        if (typeof wait !== "number") wait = 300;
        if (typeof immediate !== "boolean") immediate = false;
        var timer = null,
            result;
        return function proxy() {
            var runNow = !timer && immediate,
                params = [].slice.call(arguments),
                self = this;
            if (timer) clearTimeout(timer);
            timer = setTimeout(function () {
                if (timer) {
                    clearTimeout(timer);
                    timer = null;
                };
                !immediate ? result = func.apply(self, params) : null;
            }, wait);
            runNow ? result = func.apply(self, params) : null;
            return result;
        };
    };

    ### 函数节流
    var throttle = function throttle(func, wait) {
        if (typeof func !== "function") throw new TypeError('func must be required and be an function!');
        if (typeof wait !== "number") wait = 300;
        var timer = null,
            previous = 0,
            result;
        return function proxy() {
            var now = +new Date(),
                remaining = wait - (now - previous),
                self = this,
                params = [].slice.call(arguments);
            if (remaining <= 0) {
                if (timer) {
                    clearTimeout(timer);
                    timer = null;
                }
                result = func.apply(self, params);
                previous = +new Date();
            } else if (!timer) {
                timer = setTimeout(function () {
                    if (timer) {
                        clearTimeout(timer);
                        timer = null;
                    }
                    result = func.apply(self, params);
                    previous = +new Date();
                }, remaining);
            }
            return result;
        };
    };

    // 遍历数组/类数组/对象「支持回调函数返回值处理:返回false则结束循环,这是内置方法forEach/map不具备的」
    var each = function each(obj, callback) {
        typeof callback !== "function" ? callback = Function.prototype : null;
        var length,
            i = 0,
            keys = [];
        if (isArrayLike(obj)) {
            // 数组或者类数组
            length = obj.length;
            for (; i < length; i++) {
                var item = obj[i],
                    result = callback.call(item, item, i);
                if (result === false) break;
            }
        } else {
            // 对象
            keys = Object.keys(obj);
            typeof Symbol !== "undefined" ? keys = keys.concat(Object.getOwnPropertySymbols(obj)) : null;
            i = 0;
            length = keys.length;
            for (; i < length; i++) {
                var key = keys[i],
                    value = obj[key];
                if (callback.call(value, value, key) === false) break;
            }
        }
        return obj;
    };

    ### 实现数组和对象深/浅合并
    var merge = function merge() {
        var options,
            target = arguments[0] || {},
            i = 1,
            length = arguments.length,
            treated = arguments[length - 1],
            deep = false;
        if (typeof target === "boolean") {
            deep = target;
            target = arguments[i] || {};
            i++;
        }

        if (Array.isArray(treated) && treated.treated) {
            // 传递了记录已经处理过的内容的集合
            // 后期循环的时候少循环处理一项
            length--;
        } else {
            // 没传递,最后传递的这个值,不是用来存储处理过的内容,而是进行合并比较的
            treated = [];
            treated.treated = true;
        }

        if (typeof target !== "object" && !isFunction(target)) target = {};
        for (; i < length; i++) {
            options = arguments[i];
            if (options == null) continue;

            ### 放置死递归处理的操作
            if (treated.indexOf(options) > -1) return options;
            treated.push(options);

            each(options, function (copy, name) {
                var copyIsArray = Array.isArray(copy),
                    copyIsObject = isPlainObject(copy),
                    src = target[name],
                    clone = src;
                if (deep && copy && (copyIsArray || copyIsObject)) {
                    if (copyIsArray && !Array.isArray(src)) clone = [];
                    if (copyIsObject && !isPlainObject(src)) clone = {};
                    target[name] = merge(deep, clone, copy, treated);
                } else if (copy !== undefined) {
                    target[name] = copy;
                }
            });
        }
        return target;
    };

    ### 实现数组和对象深/浅拷贝
    var clone = function clone() {
        var target = arguments[0],
            deep = false,
            type,
            isArray,
            isObject,
            result,
            Ctor,
            treated = arguments[arguments.length - 1];
        !Array.isArray(treated) || !treated.treated ? (treated = [], treated.treated = true) : null;
        if (typeof target === "boolean") {
            deep = target;
            target = arguments[1];
        }

        // 防止死递归的处理
        if (treated.indexOf(target) > -1) return target;
        treated.push(target);

        // 校验类型
        type = toType(target);
        isArray = Array.isArray(target);
        isObject = isPlainObject(target);

        // 特殊值的拷贝
        if (target == null) return target;
        Ctor = target.constructor;
        if (/^(regexp|date)$/i.test(type)) return new Ctor(target);
        if (/^(error)$/i.test(type)) return new Ctor(target.message);
        if (/^(function|generatorfunction)$/i.test(type)) {
            return function proxy() {
                var args = Array.from(arguments);
                return target.apply(this, args);
            };
        }
        if (!isArray && !isObject) return target;

        // 如果是数组/对象,我们依次迭代赋值给新的数组/对象
        result = new Ctor();
        each(target, function (copy, name) {
            if (deep) {
                // 深拷贝
                result[name] = clone(deep, copy, treated);
                return;
            }
            // 浅拷贝
            result[name] = copy;
        });
        return result;
    };


## 获取_URL地址参数并转换为对象
 var getQueryParams = function getQueryParams(){
	const result = {}
	const queryString = window.location.search;
	const reg = /[?&][^?&] += [^?&]/g;
	const found = queryString.match(reg);

	if(found){
		found.forEach(item=>{
			let temp = item.substring(1).solit("=");
		let key = temp[0];
		let value = temp[1]
		result[key] = value;
		})
	}

	return result;
   }

### _storage的存取
const saveItem  = function saveItem(key,value){
   let storage = window.localStorage.getItem(namespace);
   if(!storage){
	storage = {}
    }else{
	storage = JSON.parse(storage)
    }
	storage[key] = value;
	window.localStorage.setItem(namespace,JSON.stringlfy(storage))
 }
const loadItem = function loadItem(key,value){
	storage = window.localStorage.getItem(namespace);
if(!storage)return def;
storage = JSON.parse(storage) 
	let result = storage[key];
	return result || def;
}
export default {
saveItem,loadItem
}

### 实现洗牌函数
const getRandomNumber = function getRandomNumber(min,max){
	// min max之间的一个数字
	// [0,1] => [min,max]
	
	return Math.floor(Math.random() * (max - min +1) + min)
}
const shuffle = function shuffle(arr){
	let _arr = arr.slice();
	for(let i=0; i<_arr.length;i++){
	const j = getRandomNumber(0,i);
	const temp = _arr[i];
	_arr[i]  = _arr[j];
	_arr[j] = temp
}
return _arr;
}
export default {
shuffle,getRandomNumber
}

### 自定义添加类名
const addClass = function addClass(){
	//1.判断添加的类名是否已经存在if(_hasClass(el,className))return
	// 2.真正的去添加类名
let newClass = el.className.split('');
	newClass.push(className)
el.className = newClass.join('');	
}
const hasClass = function hasClass(el,className){
	const reg= new RegExp('(^|\\s)' + className + '(\\s|$)');
return reg.test(el.calssName);
}

    /* 暴露API */
    var utils = {
        toType: toType,
        isFunction: isFunction,
        isWindow: isWindow,
        isArrayLike: isArrayLike,
        isPlainObject: isPlainObject,
        isEmptyObject: isEmptyObject,
        isNumeric: isNumeric,
        debounce: debounce,
        throttle: throttle,
        each: each,
        merge: merge,
        clone: clone,
	addClass:addClass,
	hasClass:hasClass,
	getRandomNumber:getRandomNumber,
	shuffle:shuffle,
	saveItem:saveItem,
	loadItem:loadItem,
    };

    // 转移_的使用权
    var $_ = window._;
    utils.noConflict = function noConflict() {
        if (window._ === utils) {
            window._ = $_;
        }
        return utils;
    };

    if (typeof window !== "undefined") {
        window._ = window.$utils = utils;
    }
    if (typeof module === "object" && typeof module.exports === "object") {
        module.exports = utils;
    }
})();
0

评论区