You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript对象内数组被意外覆盖的异常问题排查

问题根源分析

1. 原对象被修改的原因

JavaScript里数组和对象都是引用类型。你代码里let currentAvailableTimesOnDate = availableTimesPerDay[bookedDate.getDate()]这行,只是把原对象里数组的引用赋值给了新变量,并不是复制出一个新数组。之后用splice修改currentAvailableTimesOnDate,本质上就是在修改原availableTimesPerDay里的数组——因为它们指向内存里同一个数组实例。

2. 同星期几日期数组同时被修改的原因

你在生成availableTimesPerDay的时候,大概率是把同一个数组实例赋值给了所有同星期几的日期键。比如可能写了类似这样的代码:

const defaultWeekdayTimes = ["10:00","10:30","11:00","11:30","12:00"];
// 假设1、8、15号都是周一
availableTimesPerDay[1] = defaultWeekdayTimes;
availableTimesPerDay[8] = defaultWeekdayTimes;
availableTimesPerDay[15] = defaultWeekdayTimes;

这种情况下,这几个日期对应的数组都是同一个引用,修改其中一个,其他所有指向这个数组的日期键都会跟着变。而你在codepen或控制台测试时,应该是手动为每个日期单独写了数组(比如1: ["10:00",...], 8: ["10:00",...]),每个数组都是独立实例,所以不会互相影响。


解决方案

第一步:修复availableTimesPerDay的生成逻辑

确保每个日期对应的数组都是独立的副本,不要复用同一个数组引用。可以用扩展运算符或者slice()来复制数组:

const defaultWeekdayTimes = ["10:00","10:30","11:00","11:30","12:00"];
// 每个日期都赋值数组的副本
availableTimesPerDay[1] = [...defaultWeekdayTimes];
availableTimesPerDay[8] = [...defaultWeekdayTimes];
availableTimesPerDay[15] = [...defaultWeekdayTimes];

第二步:修改函数,避免修改原对象

如果不想让原availableTimesPerDay被修改,需要先创建它的深拷贝,然后在拷贝上进行操作。因为availableTimesPerDay里的值是数组,所以要深拷贝到数组层级:

function reduceAvailableTimesBasedOnDateTime(availableTimesPerDay, bookedTimes) {
    // 创建深拷贝,避免修改原对象
    const copiedAvailableTimes = {};
    for (const dateKey in availableTimesPerDay) {
        copiedAvailableTimes[dateKey] = [...availableTimesPerDay[dateKey]];
    }

    bookedTimes.forEach((bookedDateObject) => {
        const bookedDate = new Date(bookedDateObject.date);
        const dateKey = bookedDate.getDate();
        const currentAvailableTimes = copiedAvailableTimes[dateKey];
        if (!currentAvailableTimes) return; // 如果该日期没有可用时段,直接跳过

        // 注意:toLocaleTimeString的时区问题,建议明确指定时区
        const bookedTime = bookedDate.toLocaleTimeString('et', { timeZone: 'Europe/Tallinn' });
        const time = bookedTime.substring(0, bookedTime.length - 3);
        const index = currentAvailableTimes.indexOf(time);
        
        if (index > -1) {
            currentAvailableTimes.splice(index, 1);
        }
    });

    return copiedAvailableTimes;
}

这样调用函数后,原availableTimesPerDay不会被修改,返回的是修改后的新对象。

额外优化:避免时区转换问题

你代码里用toLocaleTimeString转换时间可能存在时区偏差,建议直接从ISO字符串中提取时间部分,更可靠:

// 从"2022-12-01T11:30:00.000+02:00"提取"11:30"
const time = bookedDateObject.date.slice(11, 16);

内容的提问来源于stack exchange,提问作者Banana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 19:35:30