深拷贝 浅拷贝 实际项目发现问题

76 阅读1分钟

图片.png

/**

     * 排班 日期格式处理  需要整理好每次的 event

     * @param id 该次班的员工id

     * @param date 传入排班数据

     * @param workDate 该员工排班日期

     * @return 返回需要排班的中国标准时间

     */
      传入的参数是
      // id = 1

      // date = 000011111000000000000000111100

      // workDate = 2023-05-10

    paiban_date_format(id,date,workDate){

      let date_res = Array.from(date);

      // 该员工的当日所有排班事件

      // let events = [];

      // 单个排班事件

      let event = {

        name: '',

        start: '',

        end: '',

        // color: `rgb(${this.getRandomArbitrary(0,255)},

        // ${this.getRandomArbitrary(0,255)},

        // ${this.getRandomArbitrary(0,255)}

        // )`,
        color: `rgb(255,255,255)`,

        timed: false,

      };

  


      // 员工姓名 
      /*
      this.names =
        ["经理1"
        "副经理1"
         "小组长1"
         "收银1"
         "导购1"
         "库房1"
         "收银11"
         "导购11"
         "库房11"
         "经理2"]
      */

      event.name = this.names[id];
      
      
      // -------- 重点 深拷贝 浅拷贝问题
      // 第一轮 event.start = Date Wed May 10 2023 10:00:00 GMT+0800 (中国标准时间)
      //       event.end = Date Wed May 10 2023 12:30:00 GMT+0800 (中国标准时间)
      // 第二轮 
      //       event.start = Date Wed May 10 2023 20:00:00 GMT+0800 (中国标准时间)
      //       event.end = Date Wed May 10 2023 22:00:00 GMT+0800 (中国标准时间)

      let result = [];

      for(let i=0; i<date_res.length; i++){

        // 如果找到一个 1 则向后找 有几个连续的 1 记下开始和结束的下标

        if(date_res[i] === '1'){

          // 第一个 1 保存 start

          event.start = new Date(`${workDate} ${this.dateRule[i]}`);

          // console.log(`开始保存: ${i}`);

          for(let j = i; j<date_res.length; j++){

            if(date_res[j] === '1'){

              continue;

            }else{

              // 当没有 1 时候 将结果保存 end

              event.end = new Date(`${workDate} ${this.dateRule[j]}`);

              // 将结果保存

              // 跳过 已经查询过的地方

              // events.push(event);

              console.log(event);

  


              console.log(this.events.push(event));

              i = j;

              break;

            }

          }

        }

      }

      console.log('==========');

      console.log(event);

      console.log(this.events);

      console.log('----------');

      return result;

    },

两轮给 events 赋值

  • 在赋值前 第一次 的 event 应该是:
  • 第一轮 event.start = Date Wed May 10 2023 10:00:00 GMT+0800 (中国标准时间)
  •   event.end = Date Wed May 10 2023 12:30:00 GMT+0800 (中国标准时间)
    
  • 第二次 的 event 应该是:
  • 第二轮
  • event.start = Date Wed May 10 2023 20:00:00 GMT+0800 (中国标准时间)
    
  • event.end = Date Wed May 10 2023 22:00:00 GMT+0800 (中国标准时间)
    

但是结果并不是这样的

图片.png

那问题出现在哪里呢?

  • 问题出在这里:

  • 图片.png

  • 我们需要 push 到 events 的是对象,其实 push 进去的是 event 的引用地址,也就还是原来的event

  • 第一次存储进去的是 该对象的引用,

  • 那么

  • 我们第二次 再次给 event 赋值的时候就会覆盖掉他之前的值

  • 再次 push 的时候录入的还是 这个 event 的引用,所有最终出现的结果就会是两个一样的结果

解决方法

这样只讲引用 push 进去的 是浅拷贝
我们需要 将他们使用深拷贝 push 到 events 中,这样才不会出现这样的错误

JSON.stringify()

   // 将该句 改成
      console.log(this.events.push(event)); 
  // 改成
      console.log(this.events.push(JSON.stringify()))

问题解决:

  • 重复数据消失
  • 图片.png

参考博客

# JavaScript深拷贝看这篇就行了!(实现完美的ES6+版本)