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

如何在JavaScript中从表单获取PHP风格的嵌套数组

如何将表单嵌套数组格式的name属性转为嵌套JS对象?

你说得没错,serializeArray()确实不会帮你自动解析这种嵌套的name格式——它只会返回一个扁平的数组,每个元素都是包含name和value键的对象,这就是你看到当前扁平输出的原因。要得到你期望的嵌套结构,你需要自己编写逻辑,把那些带括号的name字符串拆解并构建成嵌套对象。

解决方案:编写解析函数转换结构

我们可以写一个辅助函数,遍历serializeArray()返回的结果,然后逐个解析每个字段的name属性,把它转换成对应的嵌套层级,同时处理数组类型的字段(比如value[]这种格式)。

下面是完整的实现代码:

完整HTML(和你的原代码一致)

<form>
 <input type="hidden" name="query[taxonomy_01][value][]" value="term_01" />
 <input type="hidden" name="query[taxonomy_01][value][]" value="term_02" />
 <input type="hidden" name="query[taxonomy_02][value][]" value="term_01" />
 <input type="hidden" name="query[taxonomy_02][value][]" value="term_02" />
 <input type="hidden" name="post_type" value="news" />
 <input type="hidden" name="date_from" value="today" />
 <button type="button" class="button" >Filter content</button>
</form>

修改后的JavaScript代码

$(".button").click(function () {
  // 先获取扁平的序列化数组
  const flatData = $(this).closest('form').serializeArray();
  
  // 定义转换函数
  function convertToNestedObject(flatArray) {
    const result = {};
    
    flatArray.forEach(item => {
      let current = result;
      // 拆分name属性,比如把"query[taxonomy_01][value][]"拆分成数组
      const keys = item.name.replace(/\]/g, '').split('[');
      
      // 遍历所有键,构建嵌套结构
      for (let i = 0; i < keys.length; i++) {
        const key = keys[i];
        // 如果是最后一个键,直接赋值
        if (i === keys.length - 1) {
          // 如果当前键对应的是数组(比如value[]的情况)
          if (Array.isArray(current[key])) {
            current[key].push(item.value);
          } else if (current[key] !== undefined) {
            // 如果已经有值,转为数组
            current[key] = [current[key], item.value];
          } else {
            current[key] = item.value;
          }
        } else {
          // 如果当前层级不存在,创建空对象或数组
          if (!current[key]) {
            // 检查下一个键是否是数组格式(比如后面跟[])
            const nextKey = keys[i+1];
            current[key] = nextKey === '' ? [] : {};
          }
          current = current[key];
        }
      }
    });
    
    return result;
  }
  
  // 转换并输出结果
  const formData = convertToNestedObject(flatData);
  console.log(formData);
});

代码工作原理

  1. 拆分name属性:通过正则替换掉],再用[拆分,把query[taxonomy_01][value][]拆成['query', 'taxonomy_01', 'value', ''],最后一个空字符串表示这是一个数组。
  2. 构建嵌套层级:从根对象result开始,逐层遍历拆分后的键,不存在的层级就创建空对象或数组。
  3. 处理数组字段:如果遇到最后一个键是空字符串(对应[]),或者当前字段已经存在值,就把值转为数组并追加新元素。

运行这段代码后,你就能得到和期望一致的嵌套结构了:

{
  query: {
    taxonomy_01: {
      value: ['term_01', 'term_02']
    },
    taxonomy_02: {
      value: ['term_01', 'term_02']
    }
  },
  post_type: 'news',
  date_from: 'today'
}

补充说明

如果你不想自己写这个逻辑,也可以考虑使用第三方库(比如jQuery.param的反向解析,但原生没有这个功能),不过上面的自定义函数足够轻量且能满足你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:43:56