如何将表单的所有元素转换为JavaScript对象?

我希望有某种方法从表单自动构建JavaScript对象,而不必遍历每个元素。我不希望使用$('#formid').serialize();返回的字符串;,我也不希望$('#formid').serializeArray()返回映射;


当前回答

此代码适用于我:

  var data = $('#myForm input, #myForm select, #myForm textarea').toArray().reduce(function (m, e) {
            m[e.name] = $(e).val();
            return m;
        }, {});

其他回答

【2020年更新】

在vanilla js中有一个简单的oneliner,它利用了fromEntries(一如既往,请检查浏览器支持):

Object.fromEntries(new FormData(form))

使用lodash#set

let serialized = [
  { key: 'data[model][id]', value: 1 },
  { key: 'data[model][name]', value: 'product' },
  { key: 'sid', value: 'dh0un1hr4d' }
];

serialized.reduce(function(res, item) {
  _.set(res, item.key, item.value);
  return res;
}, {});

// returns
{
  "data": {
    "model": {
      "id": 1,
      "name": "product"
    }
  },
  "sid": "dh0un1hr4d"
}

这使用foreach方法迭代serializArray返回的名称和值对,然后使用名称作为键返回对象。

  let formData = $(this).serializeArray();
  let formObject = {}
  formData.forEach(
    x=>formObject.hasOwnProperty(x.name)?formObject[x.name]=[formObject[x.name],x.value].flat():formObject[x.name]=x.value
  );

我发现Tobias Cohen的代码有一个问题(我没有足够的分数来直接评论它),否则它对我来说是有效的。如果您有两个同名的选择选项,都是value=“”,原始代码将生成“name”:“”而不是“name”:[”,“”]

我认为这可以通过在第一个if条件中添加“||o[this.name]==''”来解决:

$.fn.serializeObject = function()
{
    var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
        if (o[this.name] || o[this.name] == '') {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};

Tobias Cohen解决方案的固定版本。此函数正确处理0和“”等错误值。

jQuery.fn.serializeObject = function() {
  var arrayData, objectData;
  arrayData = this.serializeArray();
  objectData = {};

  $.each(arrayData, function() {
    var value;

    if (this.value != null) {
      value = this.value;
    } else {
      value = '';
    }

    if (objectData[this.name] != null) {
      if (!objectData[this.name].push) {
        objectData[this.name] = [objectData[this.name]];
      }

      objectData[this.name].push(value);
    } else {
      objectData[this.name] = value;
    }
  });

  return objectData;
};

以及一个CoffeeScript版本,方便您编写代码:

jQuery.fn.serializeObject = ->
  arrayData = @serializeArray()
  objectData = {}

  $.each arrayData, ->
    if @value?
      value = @value
    else
      value = ''

    if objectData[@name]?
      unless objectData[@name].push
        objectData[@name] = [objectData[@name]]

      objectData[@name].push value
    else
      objectData[@name] = value

  return objectData