util.js 2.19 KB
/**
 * 深度克隆对象
 * @param {Object} obj 目标对象
 * @returns {Object} 克隆的新对象
 */
export const cloneDeep = (obj) => {
  if (typeof obj !== 'object') {
    return obj;
  }
  if (!obj) {
    return obj;
  }
  if (obj instanceof  Date) {
    return new Date(obj);
  } 
  if (obj instanceof  RegExp) {
    return new RegExp(obj);
  } 
  if (obj instanceof  Function) {
    return obj;
  } 
  let newObj;
  if (obj instanceof Array) {
    newObj = [];
    for(let i = 0, len = obj.length; i < len; i++){
      newObj.push(cloneDeep(obj[i]));
    }
    return newObj;
  }
  newObj = {};
  for(let key in obj) {
    if (obj.hasOwnProperty(key)) {
      if (typeof obj[key] !== 'object') {
        newObj[key] = obj[key];
      } else {
        newObj[key] = cloneDeep(obj[key]);
      }
    }
  }
  return newObj;
};

/**
 * 对象深度取值
 * @desctiption 来源于"typy.js"中src/util的getNestedObject函数
 * @param {Object} obj 目标对象
 * @param {String} dotSeparatedKeys 用分隔符".", "[", "]", "'", """隔开的取值路径
 * @example get({ a: { b: { c: ['d'] } } }, 'a.b.c.0')
 */
export const get = (obj, dotSeparatedKeys) => {
  if (dotSeparatedKeys !== undefined && typeof dotSeparatedKeys !== 'string') return undefined;
  if (typeof obj !== 'undefined' && typeof dotSeparatedKeys === 'string') {
    const splitRegex = /[.\[\]'"]/g;
    const pathArr = dotSeparatedKeys.split(splitRegex).filter(k => k !== '');
    obj = pathArr.reduce((o, key) => (o && o[key] !== undefined ? o[key] : undefined), obj);
  }
  return obj;
};

/**
 * 对象深度赋值
 * @description 改写自get方法
 * @param {Object} obj 目标对像
 * @param {String} dotSeparatedKeys 用分隔符".", "[", "]", "'", """隔开的赋值路径
 * @param {*} value 目标值
 * @example set(obj, 'a.b.c', 'd')
 */
export const set = (obj, dotSeparatedKeys, value) => {
  const splitRegex = /[.\[\]'"]/g;
  const pathArr = dotSeparatedKeys.split(splitRegex).filter(k => k !== '');
  const key = pathArr.pop();
  pathArr.reduce((o, k) => {
    if (o && o[k] === undefined || o[k] === null) {
      o[k] = !isNaN(Number(key)) ? [] : {}
    }
    return o[k]
  }, obj)[key] = value
};

export default {
  cloneDeep,
  get,
  set
}