常见工具函数实现与解析

90 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第30天,点击查看活动详情

前言

在构建企业项目的脚手架的时候,一般我们需要内置一些常见的功能函数,这些函数有些需要依赖成熟的类库,有些需要针对原型方法进行扩展,但是不可否认,一个强大的扩展函数库是提升开发效率的利器,今天,我以我司扩展函数为例,列举一些常见的又常用的扩展函数

判断不是null或者undefined

很多时候,我们需要判断某个属性不存在或者某个对象不存在,有一个扩展函数可以帮助我们写更少的代码,避免写重复的代码

function isDefine (obj) {
  return null !== obj && undefined !== obj
}

移除数组内元素

这里将数组为null以及数组为空的情况都考虑到了,避免重复处理判断和下标越界判断

export function remove (arr, item) {
  if (arr && arr.length) {
    const index = arr.indexOf(item)
    if (index > -1) {
      return arr.splice(index, 1)
    }
  }
}

判断是否是空对象

这里,布尔和数字类型不存在空对象,数组为空也认为是空对象,对象不存在自由属性也认为是空对象,此外,还有null和undefined也认为是空对象

export function validatenull (val) {
  if (typeof val === 'boolean') {
    return false
  }
  if (typeof val === 'number') {
    return false
  }
  if (val instanceof Array) {
    if (val.length === 0) return true
  } else if (val instanceof Object) {
    if (JSON.stringify(val) === '{}') return true
  } else {
    if (val === 'null' || val === null || val === 'undefined' || val === undefined || val === '') return true
    return false
  }
  return false
}

判断对象的类型

根据toString的内容来进行区分,一般来说,在需要进行条件判断的时候比较有用

export const getObjType = obj => {
  var toString = Object.prototype.toString
  var map = {
    '[object Boolean]': 'boolean',
    '[object Number]': 'number',
    '[object String]': 'string',
    '[object Function]': 'function',
    '[object Array]': 'array',
    '[object Date]': 'date',
    '[object RegExp]': 'regExp',
    '[object Undefined]': 'undefined',
    '[object Null]': 'null',
    '[object Object]': 'object'
  }
  if (obj instanceof Element) {
    return 'element'
  }
  return map[toString.call(obj)]
}

对象深拷贝

这个比较常见了,主要用于需要一个不受影响的副本,消除对象引用类型副作用时采用的函数,这里我们就需要用到上面的获取对象类型的方法了,这里需要注意几点,数组和对象需要继续进行递归深拷贝的。

export const deepClone = data => {
  var type = getObjType(data)
  var obj
  if (type === 'array') {
    obj = []
  } else if (type === 'object') {
    obj = {}
  } else {
    // 不再具有下一层次,直接返回
    return data
  }
  if (type === 'array') {
    for (var i = 0, len = data.length; i < len; i++) {
      obj.push(deepClone(data[i]))
    }
  } else if (type === 'object') {
    for (var key in data) {
      obj[key] = deepClone(data[key])
    }
  }
  return obj
}

总结

工欲善其事,必先利其器,必要的工具函数可以帮助我们编写更优雅的业务代码,但是也要注意工具函数定义的尺度和范围,尽量避免出现依赖混乱,主次不清这样的问题,任何工具,只有有利于提升效率,才是好的工具,不是所有的函数都适合进行工具封装。在考虑通用功能函数提取的同时,一定要注意原子化和边界。 尽量以 pure function 或者 柯里化函数 这样的方式来实现