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

URLSearchParams迭代器为何会跳过每隔一个的键值对?

URLSearchParams迭代时删除元素出现跳项的原因

先看你提供的函数代码:

const foo = (qs) => {
    const sp = new URLSearchParams(qs);

    console.log(`pre: ${sp}`);

    for (const [key, val] of sp.entries()) {
        console.log(`'${key}: ${val}'`);
        sp.delete(key);
    }

    console.log(`post: ${sp}`);
}

foo('a=1&b=2&c=3&d=4');

两种执行情况的输出

  • 注释sp.delete(key)时的输出:
pre: a=1&b=2&c=3&d=4
'a: 1'
'b: 2'
'c: 3'
'd: 4'
post: a=1&b=2&c=3&d=4
  • 取消注释后的输出:
pre: a=1&b=2&c=3&d=4
'a: 1'
'c: 3'
post: b=2&d=4

为什么会跳过隔一个键?

核心原因是URLSearchParams的迭代器是实时绑定集合状态的,不是创建时的快照。迭代过程就像用指针挨个遍历元素:

  1. 初始集合是[a, b, c, d],迭代器指针指向第一个元素a;
  2. 遍历a并删除它,此时集合变成[b, c, d],所有元素往前挪了一位;
  3. 迭代器指针按规则移动到下一个位置(原本的索引1),但现在这个位置对应的是原来的第三个元素c(因为b挪到了原来a的位置),于是直接跳过了b;
  4. 遍历c并删除它,集合变成[b, d],元素再次前移;
  5. 指针继续移动到下一个位置(原本的索引3),已经超出了当前集合的长度,迭代直接结束。

就这样,b和d完全没被迭代到,自然也没被删除。

解决办法

如果要在迭代时删除所有元素,先把迭代器转换成数组快照,基于快照遍历就不会受集合实时修改的影响:

const foo = (qs) => {
    const sp = new URLSearchParams(qs);

    console.log(`pre: ${sp}`);

    // 用Array.from生成条目快照,再遍历
    for (const [key, val] of Array.from(sp.entries())) {
        console.log(`'${key}: ${val}'`);
        sp.delete(key);
    }

    console.log(`post: ${sp}`);
}

foo('a=1&b=2&c=3&d=4');

执行后所有元素都会被删除,post输出为空字符串。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 15:40:23