【问题标题】:Javascript overwrites the array in several places within an objectJavascript 在对象中的多个位置覆盖数组
【发布时间】:2022-12-05 00:01:58
【问题描述】:

很抱歉这个奇怪的标题,但我遇到了一个很奇怪的问题。为了提供一些背景知识,我正在开发一个预订系统,该系统将时间范围作为管理员的输入,根据它生成可用时间,然后根据已经进行的预订减少可用时间(即管理员指定可用性从 10: 00 至 12:00,已预订至 11:30,可用时间为times = [10:00, 10:30, 11:00, 12:00])。

我有一个对象,其中包含每月每天的可用时间。

availableTimesPerDay: {
    1: ["10:00","10:30","11:00","11:30","12:00"],
    2: ["10:00","10:30","11:00","11:30","12:00"],
    3: ["10:00","10:30","11:00","11:30","12:00"],
    ....
}

其中数字代表给定月份的日期。

预订表示为对象数组,格式为:

bookedTimes = [
    {
        date: "2022-12-01T11:30:00.000+02:00"
    }
];

我计划有一个函数可以遍历每个预订并删除给定日期该时间的可用性(根据上面的示例,需要从 availableTimesPerDay[1] 中删除 11:30,将其值保留为 ["10:00","10:30","11:00","12:00"]

函数本身定义如下:

function reduceAvailableTimesBasedOnDateTime(availableTimesPerDay,bookedTimes){
    console.log(JSON.stringify(availableTimesPerDay));
    bookedTimes.forEach((bookedDateObject) => {
        let bookedDate = new Date(bookedDateObject.date); 
        // 1
        let currentAvailableTimesOnDate = availableTimesPerDay[bookedDate.getDate()];
        // ["10:00","10:30","11:00","11:30","12:00"]
        let bookedTime = bookedDate.toLocaleTimeString('et');
        // "13:30:00"
        let time = bookedTime.substring(0,bookedTime.length - 3);
        // "13:30"
        let index = currentAvailableTimesOnDate.indexOf(time);
        // 3
        if (index > -1) { 
            currentAvailableTimesOnDate.splice(index, 1);
            // ["10:00","10:30","11:00","12:00"]
        }
    })
    console.log(JSON.stringify(availableTimesPerDay));
    return availableTimesPerDay;
}

我对这个函数的理解是,我已经将一个特定的可用时间数组提取到一个新变量中,并从该数组中删除了一个特定时间。我没有对原始数据进行任何修改,我希望在这个阶段 availableTimesPerDay 保持不变。然而,当我运行我的代码时,availableTimesPerDay 被修改,即使我没有对 availableTimesPerDay 对象本身进行任何操作。

更奇怪的是,修改不只是严格地在第一个元素上进行,而是在一周中同一天的所有特定日期上进行。这是函数中定义的 console.log(availableTimesPerDay) 的控制台输出(请注意,11:30 值在 12 月 1 日、12 月 8 日、12 月 15 日等日期被删除。

booking-helper.js:94 {"1":["10:00","10:30","11:00","11:30","12:00"],"2":[],"3":[],"4":[],"5":[],"6":[],"7":[],"8":["10:00","10:30","11:00","11:30","12:00"],"9":[],"10":[],"11":[],"12":[],"13":[],"14":[],"15":["10:00","10:30","11:00","11:30","12:00"],"16":[],"17":[],"18":[],"19":[],"20":[],"21":[],"22":["10:00","10:30","11:00","11:30","12:00"],"23":[],"24":[],"25":[],"26":[],"27":[],"28":[],"29":["10:00","10:30","11:00","11:30","12:00"],"30":[],"31":[]}
booking-helper.js:105 {"1":["10:00","10:30","11:00","12:00"],"2":[],"3":[],"4":[],"5":[],"6":[],"7":[],"8":["10:00","10:30","11:00","12:00"],"9":[],"10":[],"11":[],"12":[],"13":[],"14":[],"15":["10:00","10:30","11:00","12:00"],"16":[],"17":[],"18":[],"19":[],"20":[],"21":[],"22":["10:00","10:30","11:00","12:00"],"23":[],"24":[],"25":[],"26":[],"27":[],"28":[],"29":["10:00","10:30","11:00","12:00"],"30":[],"31":[

更有趣的是,如果我将相同的函数复制到具有相同数据的 codepen 或直接从浏览器控制台调用它,它会按预期工作——它会从特定日期中删除特定时间。

【问题讨论】:

    标签: javascript


    【解决方案1】:

    当您从字符串创建新的 Date 对象时,JavaScript 会创建对原始 Date 对象的引用,而不是创建新对象。这意味着您对新 Date 对象所做的任何修改也将影响原始 Date 对象,这就是您在代码中看到更改的原因。

    此问题的一种解决方案是使用日期对象的 getTime() 方法创建一个新的 Date 对象,这将创建一个与原始对象具有相同日期和时间的新 Date 对象。这是一个例子:

    function reduceAvailableTimesBasedOnDateTime(availableTimesPerDay,bookedTimes){
        console.log(JSON.stringify(availableTimesPerDay));
        bookedTimes.forEach((bookedDateObject) => {
            // Create a new Date object using the original object's `getTime()` method
            let bookedDate = new Date(bookedDateObject.date.getTime()); 
            let currentAvailableTimesOnDate = availableTimesPerDay[bookedDate.getDate()];
            let bookedTime = bookedDate.toLocaleTimeString('et');
            let time = bookedTime.substring(0,bookedTime.length - 3);
            let index = currentAvailableTimesOnDate.indexOf(time);
            if (index > -1) { 
                currentAvailableTimesOnDate.splice(index, 1);
            }
        })
        console.log(JSON.stringify(availableTimesPerDay));
        return availableTimesPerDay;
    }
    

    另一种解决方案是使用日期对象的 toISOString() 方法创建一个新的 Date 对象,这将创建一个与原始对象具有相同日期和时间的新 Date 对象。这是一个例子:

    function reduceAvailableTimesBasedOnDateTime(availableTimesPerDay,bookedTimes){
        console.log(JSON.stringify(availableTimesPerDay));
        bookedTimes.forEach((bookedDateObject) => {
            // Create a new Date object using the original object's `toISOString()` method
            let bookedDate = new Date(bookedDateObject.date.toISOString()); 
            let currentAvailableTimesOnDate = availableTimesPerDay[bookedDate.getDate()];
            let bookedTime = bookedDate.toLocaleTimeString('et');
            let time = bookedTime.substring(0,bookedTime.length - 3);
            let index = currentAvailableTimesOnDate.indexOf(time);
            if (index > -1) { 
                currentAvailableTimesOnDate.splice(index, 1);
            }
        })
        console.log(JSON.stringify(availableTimesPerDay));
        return availableTimesPerDay;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-22
      • 2012-08-11
      • 1970-01-01
      • 1970-01-01
      • 2010-12-06
      • 2019-06-17
      • 1970-01-01
      相关资源
      最近更新 更多