记录一些常用的Utils工具函数

603 阅读3分钟

今日主要分享一些平时常用的utils工具函数,有需要的可以参考一下

时间数字转换

function formatNumber(n) {
    n = (~~n).toString()
    return n[1] ? n : '0' + n
}

这里的 ~ 是js的一个按位取反运算,一个~代表取反一次,2个就是取反2次,那不就是没变吗?其实这里是由于运算的操作值要求是整数,所以这里就可以用来去掉小数部分转换数字了。

判断对象是否为空

function isEmpty(obj) {
    let tostring = Object.prototype.toString
    if (obj == null) return true

    if (
        tostring.call(obj) == '[object Array]' ||
        tostring.call(obj) == '[object String]'
    ) {
        return obj.length === 0
    }

    if (tostring.call(obj) == '[object Object]') {
        for (let name in obj) {
            return false
        }
    }

    return true
}

这里一般用来处理接口返回得数据,针对null、空字符串、空数组,空对象判空处理。

防抖

function debounce(fn, wait) {
    let timerId=null

    wait = wait || 0

    function debounced() {
        let that = this,
            args = arguments

        if (timerId) {
            clearTimeout(timerId)
            timerId = null
        }

        timerId = setTimeout(() => {
            fn.apply(that, args)
        }, wait)
    }

    return debounced
}

节流

function throttle(fn, gapTime) {
    let _lastTime = null
    gapTime = gapTime || 0
    
    return function () {
        let that = this,
            args = arguments,
            _nowTime = + new Date()
        if (_nowTime - _lastTime > gapTime || !_lastTime) {
            fn.apply(that, args)
            _lastTime = _nowTime
        }
    }
}

对象属性转url参数

function formatOptions(options) {
    var urlOptions = ''
    for (var i in options) {
        urlOptions += i + '=' + options[i] + '&'
    }
    urlOptions = urlOptions.slice(0, urlOptions.length - 1)
    return urlOptions
}

例:{a:1,b:2,c:3} 返回:a=1&b=2&c=3

是否是数字

function isRealNum(num) {
    if (num === '' || num === null) {
        return false;
    }

    if (typeof num === 'number' && !isNaN(num)) {
        return true;
    }

    return false;
}

这里为什么不只用isNaN是因为isNaN的缺点就在于 null、空格以及空串会被按照0来处理

比较数据是否一致

function equals(a, b) {
    if (a === b) return true;
    if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime();
    if (!a || !b || (typeof a !== 'object' && typeof b !== 'object')) return a === b;
    if (a.prototype !== b.prototype) return false;
    let keys = Object.keys(a);
    if (keys.length !== Object.keys(b).length) return false;
    return keys.every(k => equals(a[k], b[k]));
}

加减法运算

/**
 * 计算
 * @param {*} l 操作数1
 * @param {*} r 操作数2
 * @param {*} sign 操作符
 * @param {*} f 精度
 */
function operate(l, r, sign, f) {
    switch (sign) {
        case '+': return (l + r) / f
        case '-': return (l - r) / f
        case '*': return (l * r) / (f * f)
        case '/': return (l / r)
    }
}
/**
 * 解决小数精度问题
 * @param {*} l 操作数1
 * @param {*} r 操作数2
 * @param {*} sign 操作符
 * fixedFloat(0.3, 0.2, '-')
 */
function fixedFloat(l, r, sign) {
    const arrL: any = split(l)
    const arrR: any = split(r)
    let fLen = Math.max(arrL[1], arrR[1])

    if (fLen === 0) {
        return operate(Number(l), Number(r), sign, 1)
    }
    const f = Math.pow(10, fLen)
    if (arrL[1] !== arrR[1]) {
        if (arrL[1] > arrR[1]) {
            arrR[0] += padding0(arrL[1] - arrR[1])
        } else {
            arrL[0] += padding0(arrR[1] - arrL[1])
        }
    }
    return operate(Number(arrL[0]), Number(arrR[0]), sign, f)
}

是否身份证

const isIDCard = (idCard) => {
    let num: any = idCard.toLowerCase().match(/\w/g)

    if (idCard.match(/^\d{17}[\dx]$/i)) {
        let sum = 0
        let times = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]

        for (let i = 0; i < 17; i++) {
            sum += parseInt(num[i], 10) * times[i]
        }

        if ('10x98765432'.charAt(sum % 11) !== num[17]) {
            return false
        }

        return !!idCard.replace(/^\d{6}(\d{4})(\d{2})(\d{2}).+$/, '$1-$2-$3')
    }

    return false
}

是否是当天

const isToday = (value) => {
    if (isString(value) || isNumber(value)) {
        value = newDate(value)
    }

    let now = new Date()
    let today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
    let start = new Date(value.getFullYear(), value.getMonth(), value.getDate())

    return today.getTime() === start.getTime()
}

获取请求参数

/**
 * 获取请求参数方法
 * @param 参数
 * paramKey : 参数名称
 * part : 非必传, 空:默认所有参数中取最后一个,search:从search中获取,hash:从hash中获取
 * caseState : 是否区分大小写,默认不区分
 */
const getQueryParam = (paramKey, part = '', caseState = false) => {
    let queryUrl = window.location.href
    if (part) {
        if (part === 'search') queryUrl = window.location.search
        if (part === 'hash') queryUrl = window.location.hash
    }
    const paramsArr = queryUrl.split('?')

    let url = ''
    if (paramsArr.length > 1) {
        url = paramsArr.reduce((pre: any, cur: any, index: Number) => {
            if (index > 0) {
                pre += '&' + cur.replace(/(\/|#)/g, '')
            }
            return pre
        }, '')
    } else {
        url = window.location.href.split('?')[1] || ''
    }
    let params: Param = {}
    // 默认转换为小写
    if (!caseState) {
        paramKey = paramKey.toLocaleLowerCase()
    }
    let urlArr = url.replace(/(\/)#[^&]*/, '').split('&')
    for (let i = 0; i < urlArr.length; i++) {
        let num = urlArr[i].indexOf('=')
        if (num > 0) {
            let key = decodeURIComponent(urlArr[i].substring(0, num))
            if (!caseState) {
                key = key.toLocaleLowerCase()
            }
            let val = urlArr[i].substring(num + 1) || ''
            try {
                val = decodeURIComponent(val)
            } catch (ex) { }
            params[key] = val
        }
    }
    return params[paramKey]
}

创建随机数

const randomString = (len = 32) => {
    const t = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnoprstuvwxyz1234567890'
    let a = t.length
    let str = ''

    for (let i = 0; i < len; i++) {
        str += t.charAt(Math.floor(Math.random() * a))
    }

    return str
}

获取hash参数

const getHashParam = (params, caseSen = false) => {
    let hash = location.hash
    let hashQMarkPos = hash.indexOf('?') // 以问号为界
    let hashQuery = hash.substring(hashQMarkPos + 1) // vue在hash中的查询参数
    let hashStrArr = hashQuery.split('&')
    let hashNewArr: Param = {}
    hashStrArr.forEach((item) => {
        let keyVal = item.split('=')
        let k = keyVal[0]
        let v = keyVal[1]
        hashNewArr[k] = v
    })
    return hashNewArr[params]
}

加载js

let scriptCaches: string[] = []
const loadJS = (src) => {
    return new Promise(resolve => {
        if (scriptCaches.includes(src)) resolve(true)
        // var oHead = document.getElementsByTagName('HEAD').item(0); 
        const scriptEL = document.createElement("script");
        scriptEL.type = "text/javascript"
        scriptEL.src = src
        document.body.appendChild(scriptEL)
        scriptEL.onload = function () {
            console.log('loaded')
            resolve(true)
        }
        scriptEL.onerror = function () {
            resolve(false)
        }
    })
}

深拷贝

const deepCopy = (obj, deep = {}) => {
    for (let i in obj) {
        if (Object.prototype.toString.call(obj[i]) === '[object Object]') {
            deep[i] = deepCopy(obj[i])
        } else if (Array.isArray(obj[i])) {
            deep[i] = deepCopy(obj[i], [])
        } else {
            deep[i] = obj[i]
        }
    }

    return deep
}