// 处理 path, path有三种形式:'a[0].b.c'、'a.0.b.c' 和 ['a','0','b','c'],需要统一处理成数组,便于后续使用
      function toArrayPath(path) {
        if (Array.isArray(path)) {
          return path;
        }
        return path.replace(/\[/g, ".").replace(/\]/g, "").split(".")
      }

      function isValidKey(key) {
        // 是否是数字的key
        const isNumberKey = !isNaN(Number(key))
        // 是否为无效的数字key,1 有效的,01 无效的
        return isNumberKey && (Number(key) + '' === key)
      }

      /**
       * @param {object} obj
       * @param {string | string[]} path
       * @param {any} value
       */
      function set(source, path, value) {
        if (typeof source !== "object") {
          return value;
        }
        toArrayPath(path).reduce((cur, pre, index, arr) => {
          if (index === arr.length - 1) { // 若遍历结束直接赋值
            cur[pre] = value;
            return null;
          } else if (pre in cur) { // 若存在对应路径,则返回找到的对象,进行下一次遍历
            return cur[pre]
          } else { // 若不存在对应路径,则创建对应对象,若下一路径是数字,新对象赋值为空数组,否则赋值为空对象
            return cur[pre] = isValidKey(arr[index + 1]) ? [] : {};
          }
        }, source)
      } 

  

  

posted on 2021-09-07 20:10  ygunoil  阅读(160)  评论(0编辑  收藏  举报