lllyin / learning

前端踩坑记
2 stars 0 forks source link

js对象安全的set #4

Closed lllyin closed 3 years ago

lllyin commented 3 years ago
/**
 * 安全创建对象
 * 示例:
 * createSafeObj(['a', 'b', 'c'], 'obj') 
 * => 
 * { a: { b: { c: 'obj' } } }
 *
 * @param {*} path
 * @param {*} data
 * @return {*} 
 */
function createSafeObj(path, data) {
  const newObj = {};
  if (path.length === 0) return data;
  path.reduce((s, v, i) => {
    if (i === path.length - 1) {
      s[v] = data;
    } else {
      s[v] = {};
    }
    return s[v];
  }, newObj);

  return newObj;
}

/**
 * 安全的给对象添加value
 * 
 * 示例
 * safeSet({ a: 1 }, 'a.b.c', ['hahah'])
 * =>
 *  { a: 1, b: { c: [ 'hahah' ] } }
 *
 * @param {*} target
 * @param {*} path
 * @param {*} data
 */
function safeSet(target, path, data, cb) {
  const pathSplit = path.split('.');
  let _parentTarget = target;
  let _mountTarget = target;

  const hint = pathSplit.find((v, i) => {
    if (_mountTarget[v]) {
      _parentTarget = _mountTarget;
      if (Object.prototype.toString.call(_mountTarget[v]) === '[object Object]') {
        _mountTarget = _mountTarget[v];
      } else {
        _mountTarget = _parentTarget;
      }
      return false;
    } else {
      const key = v;
      const value = createSafeObj(pathSplit.slice(i + 1), data);
      cb ? cb(_mountTarget, key, value) :  _mountTarget[key] = value;;

      return true;
    }
  });

  return target;
}
lllyin commented 3 years ago

示例


// => { a: 1, b: { c: [ 'hahah' ] } }
console.log(safeSet({ a: 1 }, 'a.b.c', ['hahah'], (target, key, value) => {
  target[key] = value;
}));

console.log(safeSet({ a: 1 }, 'b.c', ['xixix'])); // => { a: 1, b: { c: [ 'xixix' ] } }

console.log(createSafeObj(['a', 'b', 'c'], 'obj')); // => { a: { b: { c: 'obj' } } }