如何在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); });
代码工作原理
- 拆分name属性:通过正则替换掉
],再用[拆分,把query[taxonomy_01][value][]拆成['query', 'taxonomy_01', 'value', ''],最后一个空字符串表示这是一个数组。 - 构建嵌套层级:从根对象
result开始,逐层遍历拆分后的键,不存在的层级就创建空对象或数组。 - 处理数组字段:如果遇到最后一个键是空字符串(对应
[]),或者当前字段已经存在值,就把值转为数组并追加新元素。
运行这段代码后,你就能得到和期望一致的嵌套结构了:
{ 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
相关产品推荐
相关产品推荐

