http://jsfiddle.net/w4Wqh/1/
老实说,我认为有一种方法可以在正则表达式中做到这一点。但我想不通。所以,这有点难看的字符串操作。无论哪种方式,我认为这应该让你走上正确的轨道:
function serialize () {
var serialized = {};
$("[name]").each(function () {
var name = $(this).attr('name');
var value = $(this).val();
var nameBits = name.split('[');
var previousRef = serialized;
for(var i = 0, l = nameBits.length; i < l; i++) {
var nameBit = nameBits[i].replace(']', '');
if(!previousRef[nameBit]) {
previousRef[nameBit] = {};
}
if(i != nameBits.length - 1) {
previousRef = previousRef[nameBit];
} else if(i == nameBits.length - 1) {
previousRef[nameBit] = value;
}
}
});
return serialized;
}
console.log(serialize());
快速解释。这只是抓取具有“名称”属性的任何内容,然后对其进行迭代。对于每次迭代,它都会获取名称并将其拆分为“[”。这基本上可以让您在需要放置东西的对象中走多远。所以,对于 Person[addresses][work],你会得到 Person,addresses],work]。
然后,有棘手的部分。由于对象总是通过引用传递,我们可以查看序列化变量中是否包含“Person”。如果没有,它会添加它,并将值设置为一个空对象。它足够通用,可以用于存储更多东西,或者在必要时替换。如果没有更多需要经过的关卡,它只需获取元素的值并将其分配给它拥有的引用。否则,代码会获取对它刚刚创建的任何内容的引用,然后再次循环,执行相同的操作。所以,对于 Person[addresses][work]..
- serialized.Person 是否存在?否。将 serialized.Person 设置为 {}。这不是循环的结束,将对 serialized.Person 的引用存储为 previousRef。
- previousRef.addresses 是否存在?(serialized.Person.addresses) 否。将 previousRef.addresses 设置为 {}。这不是循环的结束,将对previousRef.addresses 的引用存储为previousRef。
- previousRef.work 存在吗?(serialized.Person.addresses.work) 否。将 previousRef.work 设置为 {}。等等。这是循环的结束。将 previousRef.work 设置为元素中的值。