JavaScript巧用对象的引用解决三级联动

       在开发过程中,我们经常会有操作需要进行三级联动操作,比较典型的如:省市区的选择,菜单栏的选择等。当我们遇到这个问题的时候,为了便于开发,我们都是通常使用第三方的插件来实现数据的联动效果。这时候按照联动数据,后端往往会给我们一段数据数据格式如图所示:

        但当数据到了前端以后,为了方便,前端往往又需要将数据再次遍历一遍,以便将参数的属性名,或者添加额外字段,而后台为了生成这么一种数据格式,也是已经经过一次遍历的。

因此,从方案上来说,最好是一遍解决问题的。而这个遍历由前端完成更为合适一点。

        这时候后端给我们的数据格式是这样的。(另外接口)

        此时我们需要做的就是根据code 拼接成合适的含有父子关系的数组。根据后端定义,code 长度为 3 时,是第一级,为 6 时为第二级,以此类推。001 的子元素为 001001, 001 的兄弟元素为 002。

遍历的代码比较简单,只是在我没有想到在这个地方,根据 对象变量存储的数据是真实对象所在地址字节时 这个概念来进行遍历的时候。对于如何编写这一函数,我无法进行。

          const arr = [
            {
              "code": "001"
            },
            {
              "code": "001001"
            },
            {
              "code": "002"
            },
            {
              "code": "002001"
            },
            {
              "code": "002002"
            },
            {
              "code": "002003"
            },
            {
              "code": "002004"
            },
            {
              "code": "002005"
            }
          ]

          //因为是值的引用,所以根据这一存储的原理,每次遍历以后都可以将之前的数据补充完整,所以遍历以便以后,
          
          // obj[001]就是code 为001 且包括其所有子元素的一个对象,
          // obj[001001]就是code 为001001 且包括其所有子元素的一个对象(不包括父元素)
          // 而我们obj[001]也早已经将数据保存到了resultArr中。这时候resultArr就是最终结果。
          // (数组也是存储的每个元素的真实所在位置的地址的一个数组)
          let obj =  new Map()  //以 key :value 的形式,根据code存放每个value
          let resultArr = []
          arr.map((currentValue, index, array) => {
            let code = currentValue.code
            obj[code] = currentValue
            //  当code长度为3时,代表为一级目录
            if (currentValue.code.length === 3) {
              resultArr.push(obj[code])
            } else {
              let auth = currentValue.auth
              let parentid = currentValue.code.substring(0, currentValue.code.length - 3)  // 获取当前currentValue的父元素的pid
              if (obj[parentid].list) {
                obj[parentid].list.push(currentValue)
              }
              else {
                obj[parentid].list = []
                obj[parentid].list.push(currentValue)
              }
            }
          })
          console.log(resultArr)

        说回原理,代码的原理在于 对于对象类数据,值的存储不是存放在栈中,而是存储在堆中,let obj = {} 实际上obj 的真实信息是这个存在与堆中的,而obj实际存储的是这个对象的地址,而使用obj时我们是根据在obj所获取的地址,找到对应的堆数据进行修改。同样的,在上述代码中,我们虽然没有直接修改 resultArr ,但我们通过修改 obj[code] 的值,对于引用obj[code] 的resultArr而言,其内值已经发生变化。简单代码如下

let obj1 = {
    name:'张三',
}
let obj2 = obj1

obj2.name = '李四'
console.log(obj1.name)  // 李四

       详细内容可以百度或者谷歌搜索 js对象的赋值的引用

 参考资料:JavaScript高级程序设计 第四章 4.1.2 复制变量值

原文地址:https://www.cnblogs.com/h246802/p/8797070.html