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

循环向数组添加对象时为何所有元素均为同一对象?

问题分析与修复

核心问题:Date对象的引用特性

你遇到的问题根源在于Date是引用类型——循环中你反复修改同一个beginning对象,而数组里所有事件的beginning字段都指向这个对象。每次调用setDate/setMonth等方法时,这个对象的实际值被修改,导致数组中所有已添加事件的beginning同步变化,最终所有元素都指向最后一次修改后的日期。

次要问题:数组concat的错误用法

response.concat(periodicalEventsArr)不会修改原response数组,因为concat方法返回新数组,原数组保持不变。需要改用push结合展开运算符来合并数组。

修复后的代码

let response: TEventResponse[] = [];
for (let i = 0; i < events.length; i++) {
    let e = events[i];
    if (!e.isPeriodical) {
        const event: TEventResponse = {
            beginning: e.beginTime,
            ending: e.endTime,
            title: e.title,
            description: e.description,
            place: e.place,
        };
        response.push(event);
    } else {
        let beginning = new Date(e.beginTime);
        const upperDate = new Date();
        upperDate.setFullYear(year);
        upperDate.setMonth(month + 1);
        upperDate.setDate(1);
        const lowerDate = new Date();
        lowerDate.setFullYear(year);
        lowerDate.setMonth(month);
        lowerDate.setDate(1);

        let dateBoundary = e.dateBoundary || upperDate;

        if (dateBoundary >= upperDate) {
            const periodicalEventsArr: TEventResponse[] = [];
            while (beginning <= dateBoundary && beginning < upperDate) {
                if (beginning >= lowerDate) {
                    // 关键修复:创建新的Date对象,避免复用同一引用
                    const event: TEventResponse = {
                        beginning: new Date(beginning),
                        ending: e.endTime,
                        title: e.title,
                        description: e.description,
                        place: e.place,
                    };

                    periodicalEventsArr.push(event);
                }
                const n = e.repeatPeriod!;
                switch (e.repeatPeriodUnit) {
                    case "DAY":
                        beginning.setDate(beginning.getDate() + n);
                        break;
                    case "WEEK":
                        beginning.setDate(beginning.getDate() + n * 7);
                        break;
                    case "MONTH":
                        beginning.setMonth(beginning.getMonth() + n);
                        break;
                    case "YEAR":
                        beginning.setFullYear(beginning.getFullYear() + n);
                        break;
                }
            }
            // 修复数组合并:将周期事件真正添加到response中
            response.push(...periodicalEventsArr);
        }
    }
}

return response;

关键修改点说明

  1. 独立Date对象:生成每个周期事件时,用new Date(beginning)复制当前日期值,让每个事件的beginning都是独立对象,后续修改原beginning不会影响已添加的事件。
  2. 修正数组合并:用response.push(...periodicalEventsArr)替代concat,确保周期事件被真正添加到结果数组。
  3. 简化边界赋值:用e.dateBoundary || upperDate替代冗余的if-else判断,精简代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 20:15:44