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

如何将封装的jQuery序列化函数转为可复用的原生JS命名函数

表单序列化函数改造方案:移除jQuery依赖并转为可复用命名函数

完全理解你的需求——把绑定在jQuery上的序列化逻辑改成独立可复用的原生JS函数,这样就能在多页面共享,甚至为后续模块化开发铺路。我已经把原jQuery插件改造成了无依赖的标准命名函数,同时保留了原有的所有功能,还做了一些易用性优化:

改造后的完整函数

function serializeObject(formNameOrElement) {
    // 兼容传入表单ID字符串或直接传入DOM元素
    const form = typeof formNameOrElement === 'string' 
        ? document.getElementById(formNameOrElement) 
        : formNameOrElement;
    
    if (!form || form.tagName !== 'FORM') {
        throw new Error('请传入有效的表单元素或表单ID');
    }

    let json = {};
    const pushCounters = {};
    const patterns = {
        validate: /^[a-zA-Z][a-zA-Z0-9_]*(?:\[(?:\d*|[a-zA-Z0-9_]+)\])*$/,
        key: /[a-zA-Z0-9_]+|(?=\[\])/,
        push: /^$/,
        fixed: /^\d+$/,
        named: /^[a-zA-Z0-9_]+$/
    };

    // 工具函数:构建嵌套结构
    const build = (base, key, value) => {
        base[key] = value;
        return base;
    };

    // 工具函数:处理数组push计数
    const pushCounter = (key) => {
        if (pushCounters[key] === undefined) {
            pushCounters[key] = 0;
        }
        return pushCounters[key]++;
    };

    // 原生方式获取表单数据,替代jQuery.serializeArray()
    const formData = new FormData(form);
    const serializedArray = Array.from(formData.entries()).map(([name, value]) => ({ name, value }));

    serializedArray.forEach(item => {
        // 跳过不符合规则的字段名
        if (!patterns.validate.test(item.name)) {
            return;
        }

        let keys = item.name.match(patterns.key);
        let merge = item.value;
        let reverseKey = item.name;

        while (keys.length > 0) {
            const k = keys.pop();
            // 移除当前层级的键名,用于反向构建
            reverseKey = reverseKey.replace(new RegExp(`\\[${k}\\]$`), '');

            if (k.match(patterns.push)) {
                merge = build([], pushCounter(reverseKey), merge);
            } else if (k.match(patterns.fixed)) {
                merge = build([], k, merge);
            } else if (k.match(patterns.named)) {
                merge = build({}, k, merge);
            }
        }

        // 实现深度合并,替代jQuery.extend(true, ...)
        const deepMerge = (target, source) => {
            for (const key in source) {
                if (source[key] instanceof Object && target[key] instanceof Object) {
                    deepMerge(target[key], source[key]);
                } else {
                    target[key] = source[key];
                }
            }
            return target;
        };
        json = deepMerge(json, merge);
    });

    return json;
}

核心改造点说明

  • 彻底移除jQuery依赖:用原生FormDataAPI获取表单数据,用DOM选择器替代jQuery的元素操作,完全不需要引入jQuery
  • 转为全局可复用函数:直接定义serializeObject全局函数,你可以把它保存到单独的form-utils.js文件里,在需要的页面通过<script src="form-utils.js"></script>引入即可使用
  • 增强参数灵活性:支持传入表单ID字符串(比如serializeObject('userForm'))或者直接传入表单DOM元素,比原插件的调用方式更灵活
  • 保留原有的序列化逻辑:所有处理嵌套字段(比如array[]、obj[key])的规则完全和原插件一致,不会改变原有功能

调用示例

在任意页面引入函数后,你可以这样调用:

  1. 通过表单ID调用:
// 假设表单ID是"loginForm"
const loginData = serializeObject('loginForm');
console.log(loginData);
  1. 通过DOM元素调用:
const formElement = document.querySelector('#signupForm');
const signupData = serializeObject(formElement);
// 提交数据或其他处理...

面向React等模块化开发的扩展

如果之后要迁移到React或者其他模块化项目,只需要把这个函数改成ES模块格式:

// form-utils.js 改为ES模块
export function serializeObject(formNameOrElement) {
    // 函数内容和上面完全一致
}

然后在React组件里导入使用:

import { serializeObject } from './form-utils.js';

function SignupForm() {
    const handleSubmit = (e) => {
        e.preventDefault();
        const formData = serializeObject(e.target);
        // 调用API提交数据...
    };

    return (
        <form onSubmit={handleSubmit}>
            {/* 表单控件 */}
        </form>
    );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:49:59