基于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 相关文章推荐
Javascript 错误处理的几种方法
Jun 13 Javascript
JQuery入门——用bind方法绑定事件处理函数应用介绍
Feb 05 Javascript
JavaScript事件委托用法分析
Jan 24 Javascript
jQuery实现百叶窗焦点图动画效果代码分享(附源码下载)
Mar 14 Javascript
利用浮层使select不可选的实现方法
Dec 03 Javascript
js实现textarea限制输入字数
Feb 13 Javascript
详解vue-cli中配置sass
Jun 21 Javascript
vue教程之toast弹框全局调用示例详解
Aug 24 Javascript
微信小程序之GET请求的实例详解
Sep 29 Javascript
分析JavaScript数组操作难点
Dec 18 Javascript
vue 项目中使用Loading组件的示例代码
Aug 31 Javascript
详解Vue的组件中data选项为什么必须是函数
Aug 17 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
php 各种应用乱码问题的解决方法
2010/05/09 PHP
鸡肋的PHP单例模式应用详解
2013/06/03 PHP
PHP数组的定义、初始化和数组元素的显示实现代码
2016/11/05 PHP
Laravel5.5 视图 - 创建视图和数据传递示例
2019/10/21 PHP
用javascript实现分割提取页面所需内容
2007/05/09 Javascript
javascript this用法小结
2008/12/19 Javascript
使用自定义setTimeout和setInterval使之可以传递参数和对象参数
2009/04/24 Javascript
扩展JavaScript功能的正确方法(译文)
2012/04/12 Javascript
javascript学习笔记(四) Number 数字类型
2012/06/19 Javascript
js实现幻灯片效果(基于jquery插件)
2013/11/05 Javascript
js获取IP地址的方法小结
2014/07/01 Javascript
javascript中attachEvent用法实例分析
2015/05/14 Javascript
jquery实现LED广告牌旋转系统图片切换效果代码分享
2015/08/26 Javascript
nodejs获取微信小程序带参数二维码实现代码
2017/04/12 NodeJs
Angular.js中定时器循环的3种方法总结
2017/04/27 Javascript
详解从买域名到使用pm2部署node.js项目全过程
2018/03/07 Javascript
Vue使用高德地图搭建实时公交应用功能(地图 + 附近站点+线路详情 + 输入提示+换乘详情)
2018/05/16 Javascript
vue.js实现的全选与全不选功能示例【基于elementui】
2018/12/03 Javascript
浅谈Vue页面级缓存解决方案feb-alive(上)
2019/04/14 Javascript
python两种遍历字典(dict)的方法比较
2014/05/29 Python
Python实现求数列和的方法示例
2018/01/12 Python
Python面向对象程序设计OOP入门教程【类,实例,继承,重载等】
2019/01/05 Python
python统计字符的个数代码实例
2020/02/07 Python
详解Python+Selenium+ChromeDriver的配置和问题解决
2021/01/19 Python
基于PyInstaller各参数的含义说明
2021/03/04 Python
倩碧香港官方网站:Clinique香港
2017/11/13 全球购物
牛津在线药房:Oxford Online Pharmacy
2020/11/16 全球购物
采购部部长岗位职责
2014/02/06 职场文书
心理学专业大学生职业生涯规划范文
2014/02/19 职场文书
客户答谢会致辞
2015/01/20 职场文书
仓管员岗位职责范本
2015/04/01 职场文书
公务员处分决定书
2015/06/25 职场文书
2016年重阳节慰问信
2015/12/01 职场文书
Python文件的操作示例的详细讲解
2021/04/08 Python
解决jupyter notebook启动后没有token的坑
2021/04/24 Python
SQL Server内存机制浅探
2022/04/06 SQL Server