Vue全局变量的内存指向分析

在开发中遇到了这样的一个工作场景,在请求接口拿到数据之后,我需要对拿到的数据进行升序降序的排序算法的计算,但是我在点击排序之后,表头莫名其妙消失了,找到原因是发现全局变量this.tableDataHeader 值发生了改变。

  			this.tableDataHeader = [res.data[0]]
            this.indexLength = Object.keys(res.data[0]).length;
            this.tableData = res.data

我修改的是this.tableData数组中的数据,那为什么this.tableDataHeader中的数据也会被修改呢?
我的处理逻辑是这样的:

   // type是升序降序类型 index 是索引 cin是列索引
        var tempColIndex = colIndex;
        //拿到所有行数长度
        const rowCount = Object.keys(this.tableData).length;
        //拿到列的长度
        const colCount = Object.keys(this.tableData[0]).length;
        // console.log("拿到第一行第一列对应的值", this.tableData[0]["child" + 2]["rdsVal"]);
        const arrData = [];
        //合计标识列
        var temp = null;

        //收集此列所有数据,进行排序 
        for (let index = 0; index < rowCount; index++) {
          if (index != 0) {
            tempColIndex = tempColIndex + colCount;
          }
          arrData.push(this.tableData[index]["child" + tempColIndex]["rdsVal"])
        }
        // 定义正则表达式 判断是否有合计或者总计
        const reg = /(?:|)[\s ]{0,2}/g;
        if (reg.test(this.tableData[0]["child1"]["rdsVal"])) {
          //将arrData数组的第一行弹出。
          temp = arrData.shift();
        }
        // 升序排序
        //2.对此列数据进行排序 Y
        if (type === 'asc') {
          this.sortNumericArray(arrData, true); //  使用升序排序算法
        } else if (type === 'desc') {
          this.sortNumericArray(arrData, false); // 使用降序排序算法
        }
        if (temp != null) {
          arrData.unshift(temp);
        }
        //重新初始化指定列的索引
        tempColIndex = colIndex;
        //3.比对原来的所有数据,按照Y的顺序重组源数据。
        for (let outIndex = 0; outIndex < arrData.length; outIndex++) {
          //遍历源数组
          for (let rowIndex = outIndex; rowIndex < rowCount; rowIndex++) {
            //初始化索引
            tempColIndex = colIndex;
            if (rowIndex != 0) {
              tempColIndex = tempColIndex + (rowIndex * colCount);
            }
            //&& rowIndex != outIndex
            if (this.tableData[rowIndex]["child" + tempColIndex]["rdsVal"] === arrData[outIndex]) {
              if (rowIndex == outIndex) {
                break;
              }
              //直接交换 
              [this.tableData[outIndex], this.tableData[rowIndex]] = [this.tableData[rowIndex], this.tableData[outIndex]];
              //1.获取属性数组 需要拿到列数个数、index起始索引 , 当前对象索引
              this.getTempArrProp(colCount, rowIndex, outIndex, "outIndex");
              this.getTempArrProp(colCount, rowIndex, outIndex, "rowIndex");
              //交换顺序
              this.changeDataProp(colCount, outIndex, rowIndex);
              //拿到对应的索引 
              break;
            }
          }
        }

methods:
//获取交换属性函数
  getTempArrProp(colCount, rowIndex, outIndex, indexFlag) {
      //1.colCount 为列的个数(用作循环生成) 这里是加了序号进来的。
      //2.tempColIndex 起始索引 (序号生成需要 tempColIndex - 1)
          //其实是child的索引
        var rowChildIndex = rowIndex * colCount; //8
         //其实是child的索引
        var outChildIndex = outIndex * colCount; //0
      if (indexFlag === "outIndex") {
        if (this.AtempPro.length > 0) {
          this.AtempPro = [];
        }
        for (let colIndex = 0; colIndex < colCount; colIndex++) {
          this.AtempPro.push("child" + (rowChildIndex + colIndex));
        }
      } else if (indexFlag === "rowIndex") {
        if (this.BtempPro.length > 0) {
          this.BtempPro = [];
        }
        for (let colIndex = 0; colIndex < colCount; colIndex++) {
          this.BtempPro.push("child" + (outChildIndex + colIndex));
        }
      }
    }
//属性交换函数
changeDataProp(colCount, outIndex, rowIndex) {
      //交换属性
      for (let propIndex = 0; propIndex < colCount; propIndex++) {
        this.tableData[outIndex][this.BtempPro[propIndex]] = this.tableData[outIndex][this.AtempPro[propIndex]];
        this.tableData[rowIndex][this.AtempPro[propIndex]] = this.tableData[rowIndex][this.BtempPro[propIndex]];
      }
      
      //对象序号交换回来。
      var tempXuHao = this.tableData[outIndex][this.BtempPro[0]]; //序号拿到
      this.tableData[outIndex][this.BtempPro[0]] = this.tableData[rowIndex][this.AtempPro[0]];
      this.tableData[rowIndex][this.AtempPro[0]] = tempXuHao;

      // 3.outIndex 起始索引 (用于对象转换以及删除属性)
      for (let colIndex = 0; colIndex < colCount; colIndex++) {
        //2.tempColIndex 起始索引 (序号生成需要 tempColIndex - 1)

        let tempObj = Object.assign({}, this.tableData);

        delete tempObj[outIndex][this.AtempPro[colIndex]];
        delete tempObj[rowIndex][this.BtempPro[colIndex]];
      }
    }
//自定义排序函数
    sortNumericArray(arr, isAscending) {
      var allNotNumbers = true; // 添加一个标记,表示是否所有元素都无法转换为数字
      arr.sort(function (a, b) {
        // 尝试将字符串转换为数字
        var numA = parseFloat(a);
        var numB = parseFloat(b);

        // 判断转换是否成功
        var isANumber = !isNaN(numA) && isFinite(numA);
        var isBNumber = !isNaN(numB) && isFinite(numB);

        if (isANumber && isBNumber) {
          // 如果两个元素都可以转换为数字,则按照数字的大小进行比较
          allNotNumbers = false; // 如果有数字存在,标记更新为 false
          return isAscending ? numA - numB : numB - numA;
        } else if (isANumber && !isBNumber) {
          // 如果只有 a 可以转换为数字,则认为 a 更小,排在前面
          allNotNumbers = false;
          return -1;
        } else if (!isANumber && isBNumber) {
          // 如果只有 b 可以转换为数字,则认为 b 更小,排在前面
          allNotNumbers = false;
          return 1;
        } else {
          // 如果两个元素都无法转换为数字,则保持原始顺序
          return 0; // 返回 0 表示相等,不进行排序
        }
      });

      if (allNotNumbers) {
        // 如果所有元素都无法转换为数字,则直接返回原数组
        return arr;
      }
      return arr;
    }

整个过程并未对表头数组进行操作,但是修改this.tableData数据就是联动影响到了表头数组,原来根本原因在于最开始的引用部分:

			this.tableDataHeader = [res.data[0]]
            this.tableData = res.data

这里指向的是同一引用地址,当操作tableData数组时,也是直接影响到了表头数组,分析出了原因那么解决方案就十分简单了,只需要通过复制数据到数组中即可:

 this.tableDataHeader = [JSON.parse(JSON.stringify(res.data[0]))]
  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值