阅读 927

js工具函数

  1. 比较是否相等
function looseEqual (a, b) {
    if (a === b) { return true }
    var isObjectA = isObject(a);
    var isObjectB = isObject(b);
    if (isObjectA && isObjectB) {
        try {
            var isArrayA = Array.isArray(a);
            var isArrayB = Array.isArray(b);
            if (isArrayA && isArrayB) {
                return a.length === b.length && a.every(function (e, i) {
                    return looseEqual(e, b[i])
                })
            } else if (a instanceof Date && b instanceof Date) {
                return a.getTime() === b.getTime()
            } else if (!isArrayA && !isArrayB) {
                var keysA = Object.keys(a);
                var keysB = Object.keys(b);
            return keysA.length === keysB.length && keysA.every(function (key) {
                return looseEqual(a[key], b[key])
            })
            } else {
                /* istanbul ignore next */
                return false
            }
        } catch (e) {
            /* istanbul ignore next */
            return false
        }
    } else if (!isObjectA && !isObjectB) {
        return String(a) === String(b)
    } else {
        return false
    }
}

// 判断是否是对象或数组
function isObject(obj) {
    return typeof obj === 'object' && obj !== null
}
// 全相等(深度)
function isEqual(obj1, obj2) {
    if (!isObject(obj1) || !isObject(obj2)) {
        // 值类型(注意,参与 equal 的一般不会是函数)
        return obj1 === obj2
    }
    if (obj1 === obj2) {
        return true
    }
    // 两个都是对象或数组,而且不相等
    // 1. 先取出 obj1 和 obj2 的 keys ,比较个数
    const obj1Keys = Object.keys(obj1)
    const obj2Keys = Object.keys(obj2)
    if (obj1Keys.length !== obj2Keys.length) {
        return false
    }
    // 2. 以 obj1 为基准,和 obj2 一次递归比较
    for (let key in obj1) {
        // 比较当前 key 的 val —— 递归!!!
        const res = isEqual(obj1[key], obj2[key])
        if (!res) {
            return false
        }
    }
    // 3. 全相等
    return true
}

复制代码
  1. 深度复制
function deepClone(obj = {}) {
    if (typeof obj !== 'object' || obj == null) {
        // obj 是 null ,或者不是对象和数组,直接返回
        return obj
    }

    // 初始化返回结果
    let result
    if (obj instanceof Array) {
        result = []
    } else {
        result = {}
    }

    for (let key in obj) {
        // 保证 key 不是原型的属性
        if (obj.hasOwnProperty(key)) {
            // 递归调用!!!
            result[key] = deepClone(obj[key])
        }
    }

    // 返回结果
    return result
}
复制代码
  1. 防抖
// 防抖
function debounce(fn, delay = 500) {
    // timer 是闭包中的
    let timer = null

    return function () {
        if (timer) {
            clearTimeout(timer)
        }
        timer = setTimeout(() => {
            fn.apply(this, arguments)
            timer = null
        }, delay)
    }
}
复制代码
  1. 节流
// 节流
function throttle(fn, delay = 100) {
    let timer = null

    return function () {
        if (timer) {
            return
        }
        timer = setTimeout(() => {
            fn.apply(this, arguments)
            timer = null
        }, delay)
    }
}
复制代码
  1. 数组拍平
function flat(arr) {
    // 验证 arr 中,还有没有深层数组 [1, 2, [3, 4]]
    const isDeep = arr.some(item => item instanceof Array)
    if (!isDeep) {
        return arr // 已经是 flatern [1, 2, 3, 4]
    }

    const res = Array.prototype.concat.apply([], arr)
    return flat(res) // 递归
}
复制代码
  1. 滚动条平滑滚动
    function getScrollTop () {
        return (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
    },
    function setScrollTop (value) {
        window.scrollTo(0, value);
        return value;
    },
    function  scrollTo (to, duration) {
        if (duration < 0) {
            this.setScrollTop(to);
            return
        }
        var diff = to - this.getScrollTop();  //距离差 300 / 1000
        if (diff === 0) return
        var step = diff / duration * 10;  //步长

    requestAnimationFrame(
        function () {
            if (Math.abs(step) > Math.abs(diff)) { //获取绝对值
                setScrollTop(that.getScrollTop() + diff);
                return;
            }
                setScrollTop(getScrollTop() + step);
            if (diff > 0 && getScrollTop() >= to || diff < 0 && getScrollTop() <= to){
                return;
            }
            scrollTo(to, duration - 16);
    });
  }
  
复制代码
  1. 格式化startTime距现在的已过时间(距离传入的时间经多了多久
function formatPassTime(startTime) {
    var currentTime = Date.parse(new Date()),
        time = currentTime - startTime,
        day = parseInt(time / (1000 * 60 * 60 * 24)),
        hour = parseInt(time / (1000 * 60 * 60)),
        min = parseInt(time / (1000 * 60)),
        month = parseInt(day / 30),
        year = parseInt(month / 12)
    if (year) return year + '年前'
    if (month) return month + '个月前'
    if (day) return day + '天前'
    if (hour) return hour + '小时前'
    if (min) return min + '分钟前'
    else return '刚刚'
}
复制代码
  1. 深度assign
function mergeDeep (
    source: Dictionary<any> = {},
    target: Dictionary<any> = {}
) {
for (const key in target) {
    const sourceProperty = source[key]
    const targetProperty = target[key]

    // Only continue deep merging if
    // both properties are objects
    if (
        isObject(sourceProperty) &&
        isObject(targetProperty)
    ) {
        source[key] = mergeDeep(sourceProperty, targetProperty)
        continue
    }
        source[key] = targetProperty
  }
        return source
}
复制代码
  1. omit排除对象中的元素
function omit(obj, fields) {
    // eslint-disable-next-line prefer-object-spread
    const shallowCopy = Object.assign({}, obj);
    for (let i = 0; i < fields.length; i += 1) {
    const key = fields[i];
    delete shallowCopy[key];
    }
    return shallowCopy;
}

复制代码
  1. pick找对象中匹配到的元素
const pick = (obj, ...fields) => {
  let pickArr = fields
  if (Array.isArray(...fields)) { // 传入的是数组
    pickArr = fields[0]
  }
  return pickArr.reduce((res, item) => {
    // eslint-disable-next-line no-prototype-builtins
    if (obj.hasOwnProperty(item)) {
      res[item] = obj[item]
    }
    return res
  }, {})
}
复制代码
  1. 返回按对象下标顺序遍历的新对象
const objectOrder = (obj) => { // 排序的函数
    var newkey = Object.keys(obj).sort() // 先用Object内置类的keys方法获取要排序对象的属性名,再利用Array原型上的sort方法对获取的属性名进行排序,newkey是一个数组
    var newObj = {}// 创建一个新的对象,用于存放排好序的键值对
    for (var i = 0; i < newkey.length; i++) { // 遍历newkey数组
        newObj[newkey[i]] = obj[newkey[i]]// 向新创建的对象中按照排好的顺序依次增加键值对
    }
    return newObj// 返回排好序的新对象
}
复制代码
  1. 生成唯一Id
function generateRandomKey(prefix) {
    if (prefix == null) {
        prefix = 'artist'
    }

    var userAgent = window.navigator.userAgent
        .replace(/[^a-zA-Z0-9]/g, '')
        .split('')
    var mid = ''
    for (var i = 0; i < 12; i++) {
        mid += userAgent[Math.round(Math.random() * (userAgent.length - 1))]
    }
    var time = new Date().getTime()

    return prefix + '_' + mid + '_' + time
}
复制代码
文章分类
前端
文章标签