some fun_


/**
 * @desc 获取 WXML 节点信息的对象
 * @param {*} selector 选择器
 * @param {*} com 自定义组件的实例对象,如在组件内使用必传
 * @returns {promise}
 */
const getNodes = (selector, com) => {
    const query = com ? com.createSelectorQuery() : wx.createSelectorQuery()
    query.selectAll(selector).boundingClientRect()
    return new Promise((reslove, reject) => {
        query.exec(([res]) => {
            res.length ? reslove(res) : reject()
        })
    })
}
/**
 * @desc 获取某个月的天数
 * @param {Number} month 如是getMonth()获取的月份 要加1
 * @param {Number} year 
 * @returns {Number}
 */
function getDays(month = new Date().getMonth() + 1, year = new Date().getFullYear()) {
    const date = new Date(`${year}-${++month}`)
    date.setDate(0)
    return date.getDate()
}


/**
 * @desc 函数防抖
 * @param {Function} func 目标函数
 * @param {Number} delay 延迟执行毫秒数
 * @param {Boolean} immediate true - 立即执行, false - 延迟执行
 */
function debounce(func, delay = 500, immediate) {
    let timer;
    return function () {
        if (timer) clearTimeout(timer);
        if (immediate) {
            let callNow = !timer;
            timer = setTimeout(() => {
                timer = null;
            }, delay);
            if (callNow) func.apply(this, arguments);
            return
        }
        timer = setTimeout(() => {
            func.apply(this, arguments);
        }, delay)

    }
}

/**
* @desc 函数节流
* @param {Function} func 目标函数
* @param {Number} delay 延迟执行毫秒数
* @param {Boolean} immediate true - 立即执行, false - 延迟执行
*/
function throttle(func, delay = 500, immediate) {
    let timer = 0;
    return function () {
        if (immediate) {
            const now = new Date().getTime();
            if (now - timer > delay) {
                func.apply(this, arguments)
                timer = now
            }
        } else {
            if (!timer) {
                timer = setTimeout(() => {
                    timer = null;
                    func.apply(this, arguments)
                }, delay)
            }
        }

    }
}

/**
 * @desc 日期格式化,将各种日期数据类型转为指定字符串格式
 * @param {String,Number} date 日期字符串,可以是毫秒数
 * @param {String} fmt 格式化参数
 * @returns {string}
 */
function dateFormat(date, fmt = "YYYY-MM-DD hh:mm:ss") {
    if (!date) {
        return ""
    }
    if (typeof date === 'string') {
        date = date.replace("-", "/");
    }
    date = new Date(date);
    const 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 (const 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;
}
/**
 * @desc 判断两个对象内容是否相等
 * @param {Object} a 对象1
 * @param {Object} b 对象2
 * @param {String} excludeProp 不检查某个字段
 * @returns {Boolean}
 */
function isObjectValueEqual(a, b, excludeProp) {
    var aProps = Object.getOwnPropertyNames(a).filter(x => x != excludeProp);
    var bProps = Object.getOwnPropertyNames(b).filter(x => x != excludeProp);

    if (aProps.length != bProps.length) {
        return false;
    }
    for (var i = 0; i < aProps.length; i++) {
        var propName = aProps[i]
        var propA = a[propName]
        var propB = b[propName]
        // 先判断两边都有相同键名
        if (!b.hasOwnProperty(propName)) return false
        if ((propA instanceof Object)) {
            if (isObjectValueEqual(propA, propB)) {
            } else {
                return false
            }
        } else if (propA !== propB) {
            return false
        } else { }
    }
    return true
}
/**
 * @desc 递归实现深拷贝
 * @param {*} obj 
 * @param {*} hash 
 */
function deepClone(obj, hash = new WeakMap()) {
    var cloneObj;
    var Constructor = obj.constructor
    switch (Constructor) {
        case RegExp:
            cloneObj = new Constructor(obj)
            break
        case Date:
            cloneObj = new Constructor(obj.getTime())
            break
        default:
            if (hash.has(obj)) return hash.get(obj)
            cloneObj = new Constructor()
            hash.set(obj, cloneObj)
    }
    for (const k in obj) {
        var item = obj[k]
        if (item && typeof item === 'object') {
            cloneObj[k] = deepClone(item)
        } else {
            cloneObj[k] = item
        }
    }
    return cloneObj
}

/**
 * 深度合并两个对象
 * @param obj1
 * @param obj2
 * @returns {*}
 */
function deepMerge(obj1, obj2) {
    obj1 = deepClone(obj1)
    Object.keys(obj2).forEach(key => {
        obj1[key] = obj1[key] && obj1[key].toString() === "[object Object]" &&
            (obj2[key] && obj2[key].toString() === "[object Object]")
            ? deepMerge(obj1[key], obj2[key])
            : (obj1[key] = obj2[key]);
    })
    return obj1;
}


/**
 * @desc 生成唯一标识符
 * @returns {String}
 */
function guid() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = Math.random() * 16 | 0,
            v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}
/**
 * @desc 递归实现数组扁平化
 * @param {Array} arr 
 * @returns {Array}
 */
function flatten(arr) {
    return arr.reduce((prev, cur) => {
        return prev.concat(Array.isArray(cur) ? flatten(cur) : cur);
    }, [])
}

/**
 * 生成指定范围随机数
 * @param n
 * @param m
 * @returns {number}
 */
export function randomByScope(n, m) {
    var result = Math.random() * (m - n) + n;
    if (result === n) {
        result = m;
    }
    return parseInt(result);
}

module.exports = {
    dateFormat,
    getDays,
    debounce,
    throttle,
    deepClone,
    deepMerge,
    isObjectValueEqual,
    randomByScope,
    getNodes,
    guid,
    flatten
}
上一篇:CSS-背景大小 | background-size


下一篇:Kotlin学习手记——集合变换,移动端开发工具