JavaScript工具函数库(非浏览器专属,持续更新)

JavaScript8 个月前4830

业务中比较常用的JavaScript工具函数,可以用在前端环境,也可以用在node服务端,统一整理,方便查阅,本文章会持续更新。

对象或数组的深拷贝

/**
 * 对象或数组的深拷贝
 * @param {*} cloneObj 被克隆的对象
 * @param {*} targetObj 克隆的目标对象
 * @param {*} isOverride 若属性重复,是否覆盖被克隆对象的属性
 */
function deepClone(cloneObj, targetObj, isOverride = true) {
    const _toString = Object.prototype.toString
    if (_toString.call(cloneObj) !== '[object Array]' && _toString.call(cloneObj) !== '[object Object]') {
        return cloneObj
    }
    var cloneTarget = _toString.call(cloneObj) === '[object Array]' ? [] : {}
    for (let key in cloneObj) {
        if (Object.prototype.hasOwnProperty.call(cloneObj, key)) {
            if (_toString.call(cloneObj[key]) === '[object Array]' || _toString.call(cloneObj[key]) === '[object Object]') {
                cloneTarget[key] = deepClone(cloneObj[key])
            } else {
                cloneTarget[key] = cloneObj[key]
            }
        }
    }
    if (targetObj && (_toString.call(cloneObj) === _toString.call(targetObj))) {
        //这里要注意,克隆的目标对象也要deepClone下
        cloneTarget = isOverride
            ? Object.assign(cloneTarget, deepClone(targetObj))
            : Object.assign(deepClone(targetObj), cloneTarget)
    }
    return cloneTarget
}

精准判断数据类型

//精准判断数据类型
function getVerifyDataTypes() {
    const types = ["String", "Number", "Boolean", "Null", "Undefined", "Function", "Object", "Array", "Date", "Error", "RegExp", "Symbol", "Map", "Set"]
    let Type = {}
    // 示例用法:Type.isString('javascript')
    for (let i = 0; i < types.length; i++) {
        Type[`is${types[i]}`] = obj => Object.prototype.toString.call(obj) === `[object ${types[i]}]`
    }
    // 判断字符串是否为json格式
    Type.isJsonStr = str => {
        if (typeof str == 'string') {
            try {
                let obj = JSON.parse(str);
                if (obj && typeof obj == 'object') {
                    return true;
                }
                return false;
            } catch (e) {
                return false;
            }
        } else {
            return false;
        }
    }
    return Type
}

日期格式化

/**
 * 日期格式化
 * @param {*} date 日期对象
 * @param {*} beforeHyphen 年月日连字符
 * @param {*} afterHyphen 时分秒连字符
 */
function formatDate(date = new Date(), beforeHyphen = '-', afterHyphen = ':') {
    const formatNumber = n => {
        n = n.toString()
        return n[1] ? n : `0${n}`
    }
    const year = date.getFullYear()
    const month = date.getMonth() + 1
    const day = date.getDate()
    const hour = date.getHours()
    const minute = date.getMinutes()
    const second = date.getSeconds()
    const ymd = [year, month, day].map(formatNumber).join(beforeHyphen)
    const hms = [hour, minute, second].map(formatNumber).join(afterHyphen)
    return `${ymd} ${hms}`
}

把时间戳转换为剩余的天、时、分、秒

/**
 * 把时间戳转换为剩余的天、时、分、秒,一般应用于倒计时场景中
 * @param {*} timestamp 时间戳
 */
function converTimestamp(timestamp) {
    const formatNumber = n => {
        n = n.toString()
        return n[1] ? n : `0${n}`
    }
    let day = Math.floor((timestamp / 1000 / 3600) / 24);
    let hour = Math.floor((timestamp / 1000 / 3600) % 24);
    let minute = Math.floor((timestamp / 1000 / 60) % 60);
    let second = Math.floor(timestamp / 1000 % 60);
    return {
      day: day,
      hour: formatNumber(hour),
      minute: formatNumber(minute),
      second: formatNumber(second)
    }
}

将有父子关系的数组转换成树形结构数据


let data = [
    { parentId: 0, id: 1, value: 'xxx' },
    { parentId: 1, id: 3, value: 'xxx' },
    { parentId: 4, id: 6, value: 'xxx' },
    { parentId: 3, id: 5, value: 'xxx' },
    { parentId: 2, id: 4, value: 'xxx' },
    { parentId: 1, id: 2, value: 'xxx' },
]

// 转换为树形Array结构
function toTreeAry(arr, pId = 0) {
    return arr
        .filter(({ parentId }) => parentId === pId)
        .map(a => ({
            ...a,
            children: toTreeAry(arr.filter(({ parentId }) => parentId !== pId), a.id)
        }))
}

// 转换为树形Object结构
function toTreeObj(arr, pId = 0) {
    let res = {}
    arr.filter(({ parentId }) => parentId === pId)
        .forEach(a => {
            res[a.id] = {
                ...a,
                children: toTreeObj(arr.filter(({ parentId }) => parentId !== pId), a.id)
            }
        })
    return res
}

console.log(toTreeAry(data))
console.log(toTreeObj(data))

获取字符串字节长度

function getByteLength(str) {
  let length = 0;
  const reg = /^[\u0000-\u00ff]$/;
  for (let i = 0; i < str.length; i += 1) {
    if (reg.test(str.charAt(i))) {
      length += 1;
    } else {
      length += 2;
    }
  }
  return length;
}

从数组中随机取出一个元素或者多个元素

var items = ['1','2','4','5','6','7','8','9','10'];
// 从数组items中随机取出一个元素
var item = items[Math.floor(Math.random()*items.length)];

// 从数组items中随机取出多个元素
function getRandomArrayElements(arr, count) {
  if (Object.prototype.toString.call(arr) !== '[object Array]') return arr;
  if (count > arr.length) count = arr.length;
  var shuffled = arr.slice(0),
    i = arr.length,
    min = i - count,
    temp,
    index;
  while (i-- > min) {
    index = Math.floor((i + 1) * Math.random());
    temp = shuffled[index];
    shuffled[index] = shuffled[i];
    shuffled[i] = temp;
  }
  return shuffled.slice(min);
}

console.log( getRandomArrayElements(items, 6) );
2 条评论

    有点东西 

    🙂 

    0
    2

    内容太少了 

    刚上线,以后会持续更新的 

    1
    1