[BUG反馈][3.8.6] 循环遍历编译后结果错误

复现代码

import { _decorator, Component, Node } from "cc";
const { ccclass, property } = _decorator;

@ccclass("MainScene")
export class MainScene extends Component {
  protected onLoad(): void {
    const map = new Map([
      ["key1", "value1"],
      ["key2", "value2"],
    ]);
    const values = [...map.values()];
    for (const v of values) {
      console.log(v);
    }
  }
}

以上代码在预览环境能正常输出结果:

但是选择web-desktop构建后输出结果变为:

AI给的问题分析

原因分析:

  1. map.values()返回 MapIterator<string>
  2. 扩展运算符 ... 在某些编译环境下可能被转换为 concat() 方法
  3. [].concat(iterator) 会将迭代器对象本身作为元素,而不是其包含的值
  4. 因此最终数组只包含一个元素: MapIterator 对象
for (const [_, v] of map) {
      console.log(v);
}

要不这样,性能可能还好点

主要不是性能问题, 是上面这种写法会导致编译后的代码是错误的

嗯 是的。哪里有问题 不过感觉不一定会优先解决这种问题 只能换个写法先绕过 慢慢等修改

:sweat_smile: 今天又踩坑里了, 没有大佬能帮忙看看吗 @jare @dumganhar

QQ_1751093347417

预览时的结果
QQ_1751093441681

构建发布后的结果
QQ_1751093399849

我最近也遇到这个问题,你用 Array.from() 替换 [...()] 试试,即把你的代码改成

public getQuestsByType(type: QuestType): Readonly<QuestData>[] {
    return Array.from(this._questTypeMap.get(type)?.values() ?? [])
}

目前发现这几个都有问题

let map = new Map();
[...map.entires()];
[...map.keys()];
[...map.values()];

具体表现就是预览时与打包构建后的表现不一致,建议提个 issue 吧

是的, 我也是暂时换成了 Array.from, 但是习惯了用 spread 经常不小心就写成这样

Github 那边 issue 都堆了几百个了, 感觉提了也白提

我创建了一个 issue,可以跟踪一下

1赞

意思就是…慎用吗

所以并不是cocos的锅

我踩过这个坑,编译后的文件如果,…运算符会被优化成contact,处理一般数组是没问题的要么换种写法,要么改target版本

使用低版本 target(ES5)时,展开操作符 ... 被转成 concat() 会导致的问题:

问题 说明
:x: 无法正确展开类数组对象(如 arguments 结果是嵌套的 array-like 对象
:x: 不支持 Set、Map、Generator 等迭代器 结果是整个对象被作为一项
:x: 不支持 Symbol.iterator 的自定义对象 会造成意料之外的数据结构
:x: 隐藏的兼容性 bug,运行时才发现 开发时难以察觉
2赞

官方也不说明到底支持到es几,文档万年es6,但很多新特性其实也已经可以正常使用了

并且甚至2.x都是没这个问题的, 但是到3.x反而出现了, 属于是反向升级一波

1赞

我升级后,预览一切正常,打包一堆错误。我也是服了。