Skip to content

lodash

core api

cloneDeep

实现思路

js
function deepClone(obj) {
  const target = {};
  const valueList = [];
  valueList.push({
    source: obj,
    target: target
  });
  const root = {
    // 要拷贝的源对象
    source: obj,
    // 要拷贝的目标对象
    target
  }
  const stack = [root];
  while (stack.length > 0) {
    const { source, target: innerTarget } = stack.pop();
    for (let inerKey in source) {
      if (Object.prototype.hasOwnProperty.call(source, inerKey)) {
        const value = source[inerKey];
        if (typeof value === 'object') {
          // 解决循环引用
          const searchValue = find(valueList, value);
          if (searchValue) {
            innerTarget[inerKey] = searchValue;
            break;
          }
          // 初始化新的对象,并将其放入父对象对应的key
          const newTarget = {};
          innerTarget[inerKey] = newTarget;
          valueList.push({
            source: value,
            target: newTarget
          });
          stack.push({
            source: value,
            target: newTarget,
          });
        } else {
          innerTarget[inerKey] = value;
        }
      }
    }
  }
  return target;
}

function find(list, value) {
  for (const obj of list) {
    if (obj.source === value) {
      return obj.target;
    }
  }
  return null;
}
js
const pick = (originObj, property) => {
  const map = new WeakMap();
  function dp(obj){
    const result = Array.isArray(obj) ? [] : {};

    const existObj = map.get(obj);

    if(existObj){
      return existObj;
    }

    map.set(obj, result);

    for(let key of Reflect.ownKeys(obj)) {
      // 只需要加一个检测,看看key是不是我们需要的属性就行
      if(obj.hasOwnProperty(key) && key === property){
        if(obj[key] && typeof obj[key] === 'object'){
          result[key] = dp(obj[key])
        } else {
          result[key] = obj[key];
        }
      }
    }

    return result;
  }

  return dp(originObj);
}