Chrome 132 中似乎存在一个错误,其中包含非常大的对象(100 万个键)。
火狐浏览器运行良好
这是一个最小的重现。
<html>
<script>
const count = 1e6; // 1e5 => OK, 1e6 => ERROR
const big = {};
for (let i = 0; i < count; i++) {
big[`key_${i}`] = { a: i, b: i * 2, c: i * 3 };
}
console.log('begin');
try {
for (let k in big) {
if (big[k] === undefined) {
throw new Error();
}
}
} catch (e) {
console.log(`for (k in big) => ERROR with count = ${count}`);
}
try {
const keys = Object.keys(big);
for (let k of keys) {
if (big[k] === undefined) {
throw new Error();
}
}
} catch (e) {
console.log(`Object.keys(big) => ERROR with count = ${count}`);
}
try {
const keys = Object.getOwnPropertyNames(big);
for (let k of keys) {
if (big[k] === undefined) {
throw new Error();
}
}
} catch (e) {
console.log(`Object.getOwnPropertyNames(big) => ERROR with count = ${count}`);
}
console.log('done');
</script>
</html>
Chrome 132 在处理包含 100 万个或更多键的非常大的对象时似乎遇到了问题。在 Firefox 中未观察到此行为,表明这可能是 Chrome 特有的错误。为了防止 Chrome 132 中出现这些错误,您可以尝试以下方法: 将对象分块 您可以将其拆分为更小的块,而不是创建单个大对象: JavaScript
const chunkSize = 1e5; // 100,000 keys per chunk
const chunks = [];
for (let i = 0; i < count; i += chunkSize) {
const chunk = {};
for (let j = 0; j < chunkSize && i + j < count; j++) {
chunk[`key_${i + j}`] = { a: i + j, b: (i + j) * 2, c: (i + j) * 3 };
}
chunks.push(chunk);
}
// Iterate over chunks
chunks.forEach(chunk => {
for (let k in chunk) {
if (chunk[k] === undefined) {
throw new Error();
}
}
});
使用地图代替对象 对于大型集合,使用 Map 可以更高效且不易出现问题: JavaScript
const big = new Map();
for (let i = 0; i < count; i++) {
big.set(`key_${i}`, { a: i, b: i * 2, c: i * 3 });
}
// Iterate over the Map
for (let [k, v] of big) {
if (v === undefined) {
throw new Error();
}
}
延迟加载 如果您不需要一次需要所有数据,请考虑延迟加载或按需生成数据: JavaScript
function* generateBigObject() {
for (let i = 0; i < count; i++) {
yield [`key_${i}`, { a: i, b: i * 2, c: i * 3 }];
}
}
const bigIterator = generateBigObject();
// Use the iterator as needed
for (let [k, v] of bigIterator) {
if (v === undefined) {
throw new Error();
}
}
异步处理 为了避免阻塞主线程并可能触发超时,您可以异步处理数据: JavaScript
async function processBigObject() {
const big = {};
for (let i = 0; i < count; i++) {
big[`key_${i}`] = { a: i, b: i * 2, c: i * 3 };
if (i % 10000 === 0) {
await new Promise(resolve => setTimeout(resolve, 0));
}
}
return big;
}
processBigObject().then(big => {
// Process the object here
});
这些方法应该有助于缓解您在 Chrome 132 中使用非常大的对象时遇到的问题。如果问题仍然存在,您可能需要将其作为错误报告给 Chromium 项目5。