function nodeMap(
  target,
  callback = () => null,
  { childKey = 'children', mapChildKey = 'children' } = {
    /* TreeNode */
  }
) {
  const dfs = (node) => {
    if (isObject(node) && !isArray(node[childKey])) {
      const _cloneNode = { ...node }
      return callback(_cloneNode, node, true)
    }
    const cloneNode = { ...node }
    const newNode = callback(cloneNode, node, false)
    if (typeof newNode[childKey] !== 'undefined') delete newNode[childKey]
    newNode[mapChildKey] = []
    for (let i = 0; i < node[childKey].length; i++) {
      const _node = node[childKey][i]
      const ret = dfs(_node)
      ret.parent = newNode
      newNode[mapChildKey].push(ret)
    }

    return newNode
  }

  return dfs(target)
}
Deep traversal of the object
@param {object} target
@param {function} callback(cloneRawNode, rawNode, isLeaf)