打造自己的JavaScript工具库(1. 数据类型校验)

生产力有两项,一项是人,一项是工具。工具用得好不好,决定我们下班早不早。

前言

我们在业务开发过程中,经常会重复用到数据类型校验,日期格式化、数据加密、随机数生成、节流函数等工具方法,这些工具类函数,适当封装整理方便拿来就用,可以提高开发效率。

数据类型校验

也许你喜欢把方法封装成ES6 Class 的method,但是考虑到使用的时候还需要实例化比较麻烦(可能你要反驳,写成static不就可以了吗,当然可以),不过我还是习惯把方法挂在对象的属性上,如下:

const Validator = {};

/**
 * 判断是否是数字, 如:'123.1' 、123.1 都是true
 *
 * @static
 * @param {any} value
 * @returns
 */
Validator.isNumber = (value) => {
  const re = /^[0-9]+\.?[0-9]*$/;
  return re.test(value);
};

/**
 * 整形数字: 2=true; '2'=true
 *
 * @static
 * @param {any} value
 * @returns
 */
Validator.isIntNumber = (value) => {
  if (value === '0' || value === 0) {
    return true;
  }
  const re = /^[1-9]+[0-9]*]*$/;
  return re.test(value);
};

/**
 * 整形数 2 = true; '2' = false
 * 这个方法会严格区分string类型的数字
 * @static
 * @param {any} val
 * @returns
 */
Validator.isInt = (val) => {
  if (Validator.isIntNumber(val)) {
    return typeof val === 'number';
  }
  return false;
};

/**
 * 是不是浮点型, 如:'123.1' = false 、123.1 = true
 *
 * @static
 * @param {any} value
 * @returns
 */
Validator.isFloat = (value) => {
  const result = Validator.isNumber(value);
  return result && parseFloat === value;
};

/**
 * 时间戳判断
 *
 * @static
 * @param {any} value
 * @returns
 */
Validator.isTimestamp = (value) => {
  return typeof value === 'number';
};

/**
 * 验证手机号
 *
 * @static
 * @param {any} value
 * @returns
 */
Validator.isPhone = (value) => {
  const reg = /^0?(1[34578])[0-9]{9}$/;
  return reg.test(value);
};

/**
 * Url验证
 *
 * @static
 * @param {any} value
 * @returns
 */
Validator.isUrl = (value) => {
  const strRegex = /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/;
  return strRegex.test(value);
};

/**
 * 是否大写字母
 *
 * @static
 * @param {any} value
 * @returns
 */
Validator.isCapital = (value) => {
  const reg = /[A-Z]/;
  return reg.test(value);
};

/**
 * 是否为空
 *
 * @static
 * @param {any} value
 * @returns
 */
Validator.isEmpty = (value) => {
  // return value?true:false;
  return !!value;
};

/**
 * 是否是一个对象
 *
 * @static
 * @param {any} value 要判断的对象
 * @returns
 */
Validator.isObject = (value) => {
  const keys = Object.keys(value);
  const values = Object.values(value);
  console.log('is object typeof value is:', typeof value);
  return keys.length > 0 && values.length > 0 && typeof value === 'object';
};

/**
 * 是否为空
 *
 * @static
 * @param {any} value
 * @returns
 */
Validator.isNotEmpty = (value) => {
  return !this.isEmpty(value);
};

Validator.isMobilePhone = (value) => {
  const reg = /^(\+?0?86\-?)?1[345789]\d{9}$/;
  return reg.test(value);
};
/**
 * 是否是monogoDB里的objectId值
 *
 * @static
 * @param {any} value
 * @returns
 */
Validator.isMongoDBObjectId = (value) => {
  return objectId.isValid(value);
};

/**
 * 此方法特殊方法。obj只能传一个对象。
 *
 * @static
 * @param {any} obj 对象
 * @param {any} value 值
 */
Validator.isObjectValue = (obj, value) => {
  if (!Validator.isObject(obj)) {
    return false;
  }

  return Object.values(obj).includes(value);
};

/**
 * 检测邮箱
 * @param email
 * @returns {boolean}
 */
Validator.testEmail = (email) => {
  const reg = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
  return reg.test(email);
};

/**
 * 身份证号码验证
 *
 * @param cardNo {String} 证件号码
 * @returns info {Object} 身份证信息.
 *
 */
Validator.getIdCardInfo = (cardNo) => {
  const info = {
    isTrue: false, // 身份证号是否有效。默认为 false
    year: null, // 出生年。默认为null
    month: null, // 出生月。默认为null
    day: null, // 出生日。默认为null
    isMale: false, // 是否为男性。默认false
    isFemale: false, // 是否为女性。默认false
  };

  if (!cardNo && cardNo.length !== 15 && cardNo.length !== 18) {
    info.isTrue = false;
    return info;
  }

  if (cardNo.length === 15) {
    const year = cardNo.substring(6, 8);
    const month = cardNo.substring(8, 10);
    const day = cardNo.substring(10, 12);
    const p = cardNo.substring(14, 15); // 性别位
    const birthday = new Date(year,
      parseFloat(month) - 1,
      parseFloat(day), 12, 0, 0, 0);

    // 对于老身份证中的年龄则不需考虑千年虫问题而使用getYear()方法
    if (birthday.getYear() !== parseFloat(year) ||
      birthday.getMonth() !== parseFloat(month) - 1 ||
      birthday.getDate() !== parseFloat(day)) {
      info.isTrue = false;
    } else {
      info.isTrue = true;
      info.year = birthday.getFullYear();
      info.month = birthday.getMonth() + 1;
      info.day = birthday.getDate();
      if (p % 2 === 0) {
        info.isFemale = true;
        info.isMale = false;
      } else {
        info.isFemale = false;
        info.isMale = true;
      }
    }
    return info;
  }

  if (cardNo.length === 18) {
    const year = cardNo.substring(6, 10);
    const month = cardNo.substring(10, 12);
    const day = cardNo.substring(12, 14);
    const p = cardNo.substring(14, 17);
    const birthday = new Date(year,
      parseFloat(month) - 1,
      parseFloat(day), 12, 0, 0, 0);

    // 这里用getFullYear()获取年份,避免千年虫问题
    if (birthday.getFullYear() !== parseFloat(year) ||
      birthday.getMonth() !== parseFloat(month) - 1 ||
      birthday.getDate() !== parseFloat(day)) {
      info.isTrue = false;
      return info;
    }

    const Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1]; // 加权因子
    const Y = [1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2]; // 身份证验证位值.10代表X

    // 验证校验位
    let sum = 0; // 声明加权求和变量
    const _cardNo = cardNo.split('');

    if (_cardNo[17].toLowerCase() === 'x') {
      _cardNo[17] = 10; // 将最后位为x的验证码替换为10方便后续操作
    }
    for (let i = 0; i < 17; i++) {
      sum += Wi[i] * _cardNo[i]; // 加权求和
    }
    const i = sum % 11; // 得到验证码所位置

    if (_cardNo[17] !== Y[i]) {
      info.isTrue = false;
      return info;
    }

    info.isTrue = true;
    info.year = birthday.getFullYear();
    info.month = birthday.getMonth() + 1;
    info.day = birthday.getDate();

    if (p % 2 === 0) {
      info.isFemale = true;
      info.isMale = false;
    } else {
      info.isFemale = false;
      info.isMale = true;
    }
    return info;
  }
  return info;
};

总结

工欲善其事必先利其器。有了属于自己的这把利器,也许才能在抗议加班的时候不至于太怂~

你可能感兴趣的:(打造自己的JavaScript工具库(1. 数据类型校验))