基于JavaScript将表单序列化类型的数据转化成对象的处理(允许对象中包含对象)


Posted in Javascript onDecember 28, 2015

表单序列化类型的数据是指url传递的数据的格式,形如"key=value&key=value&key=value"这样的key/value的键值对。一般来说使用jQuery的$.fn.serialize函数能达到这样的效果。如何将这样的格式转化为对象?

我们知道使用jQuery的$.fn.serializeArray函数得到的是一个如下结构的对象

[
  {
    name: "startTime"
    value: "2015-12-02 00:00:00"
  },
  {
    name: "endTime"
    value: "2015-12-25 23:59:59"
  }
]

这是一个对象数组,但有时候我们希望得到的是如下结构的对象

{
  "startTime": "2015-12-02 00:00:00"
  "endTime": "2015-12-25 23:59:59"
}

所以这里需要一个转化函数。

处理步骤如下:

1.使用"&"分隔将每一个键值对分开然后循环处理每一个键值对

var properties = serializedParams.split("&");
  for (var i = 0; i < properties.length; i++) {
    //处理每一个键值对
    evalThem(properties[i]);
  };

2.从"="符号切分指定的键值对,并对每个键和值使用decodeURIComponent解析uri 组件编码(因为url传递的序列化数据一般都是经过uri组件编码的)

var strAry = new Array();
    strAry = str.split("=");
    //使用decodeURIComponent解析uri 组件编码
    for(var i = 0; i < strAry.length; i++){
      strAry[i] = decodeURIComponent(strAry[i]);
    }
    var attributeName = strAry[0];
    var attributeValue = strAry[1].trim();

3.如果值包含"="符号,需要额外处理(值合并)。       

if(strAry.length > 2){
      for(var i = 2;i<strAry.length;i++){
        attributeValue += "="+strAry[i].trim();
      }
    }

这里面有一个处理,就是值没有的时候就不会往最终对象里面添加。这个可以根据自己的情况选择删除这段代码与否

if(!attributeValue){
      return ;
    }

4.如果键是“obj.obj.obj”这种由"."符号链接的,需要将它作为对象包含对象来处理。处理的方法是将键通过"."分解,然后去查看临时对象obj中是否已经包含分解出来的对象,如果是则将数据附加到已有的对象上。源码如下  

var attriNames = attributeName.split("."),
      curObj = obj;
    for(var i = 0; i < (attriNames.length - 1); i++){
      curObj[attriNames[i]]?"":(curObj[attriNames[i]] = {});
      curObj = curObj[attriNames[i]];
    }
    curObj[attriNames[i]] = attributeValue.trim();

这里面我们看到网上有对赋值部分是这么处理的

eval("obj."+attributeName+"=\""+attributeValue.trim()+"\";");

这个很有问题,一个是不能正确处理4中对象包含对象的问题(尤其是有两个元素拥有同一个父对象的时候,比如"test.id=1&test.name='chua'"都拥有父对象test)。另外一个就是值attributeValue中包含单引号、双引号时无法正确处理。所以使用赋值"="最保险。

所以最终完整的源码如下

/*
serializedParams格式为"key1=value1&key2=value2". 
也支持'key.sonkey=value' 
 */
function paramString2obj (serializedParams) {  
  var obj={};
  function evalThem (str) {
    var strAry = new Array();
    strAry = str.split("=");
    //使用decodeURIComponent解析uri 组件编码
    for(var i = 0; i < strAry.length; i++){
      strAry[i] = decodeURIComponent(strAry[i]);
    }
    var attributeName = strAry[0];
    var attributeValue = strAry[1].trim();
    //如果值中包含"="符号,需要合并值
    if(strAry.length > 2){
      for(var i = 2;i<strAry.length;i++){
        attributeValue += "="+strAry[i].trim();
      }
    }
    if(!attributeValue){
      return ;
    }
    var attriNames = attributeName.split("."),
      curObj = obj;
    for(var i = 0; i < (attriNames.length - 1); i++){
      curObj[attriNames[i]]?"":(curObj[attriNames[i]] = {});
      curObj = curObj[attriNames[i]];
    }
    //使用赋值方式obj[attributeName] = attributeValue.trim();替换
    //eval("obj."+attributeName+"=\""+attributeValue.trim()+"\";");
    //解决值attributeValue中包含单引号、双引号时无法处理的问题
    curObj[attriNames[i]] = attributeValue.trim();
  };
  var properties = serializedParams.split("&");
  for (var i = 0; i < properties.length; i++) {
    //处理每一个键值对
    evalThem(properties[i]);
  };
  return obj;
}

以上内容是基于JavaScript将表单序列化类型的数据转化成对象的处理(允许对象中包含对象),希望本文分享能够给大家带来帮助。

Javascript 相关文章推荐
为jquery.ui.dialog 增加“自动记住关闭时的位置”的功能
Nov 24 Javascript
为JavaScript提供睡眠功能(sleep) 自编译JS引擎
Aug 16 Javascript
表格单元格交错着色实现思路及代码
Apr 01 Javascript
让jQuery Mobile不显示讨厌loading界面的方法
Feb 19 Javascript
JS实现黑客帝国文字下落效果
Sep 01 Javascript
js中使用使用原型(prototype)定义方法的好处详解
Jul 04 Javascript
easyui-datagrid特殊字符不能显示的处理方法
Apr 12 Javascript
sortable+element 实现表格行拖拽的方法示例
Jun 07 Javascript
通过实例学习React中事件节流防抖
Jun 17 Javascript
bootstrap-table+treegrid实现树形表格
Jul 26 Javascript
Vue.js 无限滚动列表性能优化方案
Dec 02 Javascript
Ajax实现页面无刷新留言效果
Mar 24 Javascript
浅析JS运动
Dec 28 #Javascript
基于JavaScript实现网页倒计时自动跳转代码
Dec 28 #Javascript
js时间戳转为日期格式的方法
Dec 28 #Javascript
jquery实现全屏滚动
Dec 28 #Javascript
AngularJS使用angular-formly进行表单验证
Dec 27 #Javascript
延时加载JavaScript代码提高速度
Dec 27 #Javascript
AngularJS使用ngMessages进行表单验证
Dec 27 #Javascript
You might like
QueryPath PHP 中的jQuery
2010/04/11 PHP
php获取服务器端mac和客户端mac的地址支持WIN/LINUX
2014/05/15 PHP
PHP中的命名空间相关概念浅析
2015/01/22 PHP
PHP实现批量删除(封装)
2017/04/28 PHP
基于jquery的多功能软键盘插件
2012/07/25 Javascript
JavaScript的事件绑定(方便不支持js的时候)
2013/10/01 Javascript
纯JS实现动态时间显示代码
2014/02/08 Javascript
分享28款免费实用的 JQuery 图片和内容滑块插件
2014/12/15 Javascript
jQuery知识点整理
2015/01/30 Javascript
js代码实现无缝滚动(文字和图片)
2015/08/20 Javascript
ionic实现滑动的三种方式
2016/08/27 Javascript
JS实现页面中所有img对象添加onclick事件及新窗口查看图片的方法
2016/12/27 Javascript
详解Vue 动态添加模板的几种方法
2017/04/25 Javascript
详解关于react-redux中的connect用法介绍及原理解析
2017/09/11 Javascript
微信小程序实现日历效果
2018/12/28 Javascript
vue实现图片懒加载的方法分析
2020/02/05 Javascript
JavaScript 中的无穷数(Infinity)详解
2020/02/13 Javascript
基于Vue sessionStorage实现保留搜索框搜索内容
2020/06/01 Javascript
js实现简单的无缝轮播效果
2020/09/05 Javascript
[04:48]DOTA2亚洲邀请赛林书豪为VGJ加油
2017/04/01 DOTA
Python文件夹与文件的操作实现代码
2014/07/13 Python
python实现括号匹配的思路详解
2018/08/23 Python
python绘制直方图和密度图的实例
2019/07/08 Python
Python 处理文件的几种方式
2019/08/23 Python
Pandas聚合运算和分组运算的实现示例
2019/10/17 Python
关于numpy中eye和identity的区别详解
2019/11/29 Python
基于Python采集爬取微信公众号历史数据
2020/11/27 Python
css3 clip实现圆环进度条的示例代码
2018/02/07 HTML / CSS
英国家用电器折扣网站:Electrical Discount UK
2018/09/17 全球购物
Exoticca英国:以最优惠的价格提供豪华异国情调旅行
2018/10/18 全球购物
Tom Dixon官网:英国照明及家具设计和制造公司
2019/03/01 全球购物
调研汇报材料范文
2014/08/17 职场文书
2014预备党员批评与自我批评思想汇报
2014/09/20 职场文书
Java面试题冲刺第十五天--设计模式
2021/08/07 面试题
python编程项目中线上问题排查与解决
2021/11/01 Python
Golang 链表的学习和使用
2022/04/19 Golang