字符串解析成可执行 JSON 串

789 阅读1分钟

一、作用

  1. 字符串解析成可执行变量,监听数据的变化方便快捷,类比 Vue 中 watch 一个字符串。
  2. 处理接口数据的容错率,链选报错的一种解决方案。
  3. 快捷设置数据对象。

二、代码

// ./strToJSON.js

/**
 * @description: 将字符串解析成 JSON 串
 * @param {*} str 字符串
 * @param {*} obj 数组 | 对象
 * @param {*} val 值
 * @return {*} 获取的值 | 设置后的值
 */

const delArrList = (arr = [], arrList = [], val, flag) => {
  const li = arrList.shift()
  if (arrList.length > 0) {
    if (arr[li]) {
      return delArrList(arr[li], arrList, val, flag)
    }
  }
  
  if (val !== undefined && flag) {
    arr[li] = val
  }
  return arr[li]
}

const delArr = (arr = [], obj = {}, val, flag) => {
  if (arr[0].indexOf('[') > -1) {
    const left = arr[0].split('[')
    const arrList = []
    left.forEach(v => {
      if (v.indexOf(']') > -1) {
        const right = v.split(']')
        arrList.push(right[0])
      }
    })
    
    return delArrList(left[0] ? obj[left[0]] : obj, arrList, val, flag)
  }

  if (val !== undefined && flag) {
    obj[arr[0]] = val
  }
  return obj[arr[0]]
}

export const getStrJSON = (str, obj, val) => {
  const arr = str.split('.')
  if (arr.slice(1).length > 0) {
    const newStr = arr.slice(1).join('.')
    const ret = delArr(arr, obj, val)
    if (ret) {
      return getStrJSON(newStr, ret, val)
    }
  } else {
    return delArr(arr, obj, val, true)
  }
}

export const setStrJSON = (str, obj, val) => {
  const newObj = JSON.parse(JSON.stringify(obj))
  getStrJSON(str, newObj, val)
  return newObj
}

三、使用示例

  1. 获取值

    import { getStrJSON } from './strToJSON.js'
    
    const str = 'a[1][0][0].d[0].c'
    const str2 = 'a[1][0][0].e.c'
    const obj = { a: [{ b: {} }, [[{ d: [{ c: { e: [54] } }] }]]] }
    
    getStrJSON(str, obj) // { e: [54] }
    getStrJSON(str2, obj) // undefined  # 不会报错
    
  2. 设置值

    import { setStrJSON } from './strToJSON.js'
    
    const str = 'a[1][0][0].d[0].c'
    const str2 = 'a[1][0][0].d[2]'
    const obj = { a: [{ b: {} }, [[{ d: [{ c: { e: [54] } }] }]]] }
    
    setStrJSON(str, obj, { abc: 23 }) // { a: [{ b: {} }, [[{ d: [{ c: { abc: 23 } }] }]]] } # 不会改变原对象 obj
    setStrJSON(str2, obj, { abc: 23 }) // {"a":[{"b":{}},[[{"d":[{"c":{"e":[54]}},null,{"abc":23}]}]]]}