js中json遍历及copy

742 阅读1分钟

json遍历的本质是对树结构的访问,个人认为除了js中自带的数据结构外,每一个前端同学最需要掌握的两种数据结构就是链表与树,理解前者有利于了解作用域链和原型链相关概念,树结构在日常开发中处处可见,本文通过两个常见面试题来介绍JSON的遍历。

一、js中遍历对象的两种方式

  1. for in for in可遍历原型链上扩展的属性
  2. Object.keys(obj).forEach 只遍历自身属性

二、如何遍历json

// dfs遍历

const json = {
  a: { b: { c: 1 } },
  d: [1, 2],
}

function dfs(n) {
  console.log(n)
  Object.keys(n).forEach((key) => {
    dfs(n[key])
  })
}

dfs(json)

三、json深copy

我们可以想象是根据一个树结构,构建一个新的树,生成每一个节点,最后通过后续遍历再让其建立联系

function deepClone(obj={}) {
    if(typeof obj !== 'object' || obj == null) return obj
    const result = obj instanceof Array ? [] : {}
    Object.keys(json).forEach(key=> {
	result[key] = deepClone(json[key])
    })
    return result
}

四、json修改

// 转为驼峰
const obj = {
    "user_list": [
	{
	    "user_id": "1234",
	    "nick_name": "aaaa",
	    "friedns": {
		"user_id": "2222",
		"nick_name": "aaaa",
	    }
	},
	"userId": "1234",
	"nick_name": "aaaa"
    ]
}

function dfs(node) {  
    if (node == null || typeof node !== 'object') return node  
    const result = Array.isArray(node) ? [] : {}  
    Object.keys(node).forEach((key) => {    
        const newKey = key.replace(/_([a-z])/, (v) => v[1].toUpperCase())   
        result[newKey] = dfs(node[key])  
    })  
    return result
}

五、根据虚拟dom构建真实dom

function createEle(vNode) {
  if (vNode && vNode.tag == null) {
    return document.createTextNode(vNode)
  }

  const ele = document.createElement(vNode.tag)
  Object.keys(vNode.props).forEach((key) => {
    if (key === 'style') {
      Object.keys(vNode.props.style).forEach((property) => {
        ele.style[property] = vNode.props.style[property]
      })
    }else {
	ele.setAttribute(key, vNode.props[key])
    }
  })
  vNode.children.forEach((node) => {
    ele.appendChild(createEle(node))
  })
  return ele
}

后记

树相关的操作,依赖递归,因为几乎树所有的操作都是需要对其进行遍历的,但可喜的是树的相关操作存在及强的模式化、大部分都围绕着dfs,回溯查找、分治,以及今天我们学习的树的copy。掌握这四类通用模版后就可以解决大部分树结构问题。