如何序列化一个对象到一个参数列表?

不知道一个JavaScript Object的关键字,我怎么能变成像…

 var obj = { param1: 'something', param2: 'somethingelse', param3: 'another' } obj[param4] = 'yetanother'; 

… INTO …

 var str = 'param1=something&param2=somethingelse&param3=another&param4=yetanother'; 

…?

 var str = ""; for (var key in obj) { if (str != "") { str += "&"; } str += key + "=" + encodeURIComponent(obj[key]); } 

例如: http : //jsfiddle.net/WFPen/

如果你使用jQuery,这是用来参数化GET ajax请求的选项的:

 $.param( obj ) 

http://api.jquery.com/jQuery.param/

一个优雅的(假设你正在运行一个现代的浏览器或节点)

 var str = Object.keys(obj).map(function(key) { return key + '=' + obj[key]; }).join('&'); 

对于一个深度…

 var serialiseObject = function(obj) { var pairs = []; for (var prop in obj) { if (!obj.hasOwnProperty(prop)) { continue; } pairs.push(prop + '=' + obj[prop]); } return pairs.join('&'); } 

jsFiddle 。

有关于任意深度对象的recursion函数的讨论

 var serialiseObject = function(obj) { var pairs = []; for (var prop in obj) { if (!obj.hasOwnProperty(prop)) { continue; } if (Object.prototype.toString.call(obj[prop]) == '[object Object]') { pairs.push(serialiseObject(obj[prop])); continue; } pairs.push(prop + '=' + obj[prop]); } return pairs.join('&'); } 

jsFiddle 。

这当然意味着嵌套上下文在序列化中丢失了。

如果这些值不是以URL开始的编码,而您打算在URL中使用它们,请查看JavaScript的encodeURIComponent()

ES2017方法

 Object.entries(obj).map(([key, val]) => `${key}=${val}`).join('&') 

ES6:

 function params(data) { return Object.keys(data).map(key => `${key}=${encodeURIComponent(data[key])}`).join('&'); } console.log(params({foo: 'bar'})); console.log(params({foo: 'bar', baz: 'qux$'})); 

只是为了logging,如果你有一个浏览器支持ES6,这是一个解决scheme与reduce

 Object.keys(obj).reduce((prev, key, i) => ( `${prev}${i!==0?'&':''}${key}=${obj[key]}` ), ''); 

这里有一个片段在行动!

 // Just for test purposes let obj = {param1: 12, param2: "test"}; // Actual solution let result = Object.keys(obj).reduce((prev, key, i) => ( `${prev}${i!==0?'&':''}${key}=${obj[key]}` ), ''); // Run the snippet to show what happens! console.log(result); 

由于我对recursion函数做了如此大的处理,这里是我自己的版本。

 function objectParametize(obj, delimeter, q) { var str = new Array(); if (!delimeter) delimeter = '&'; for (var key in obj) { switch (typeof obj[key]) { case 'string': case 'number': str[str.length] = key + '=' + obj[key]; break; case 'object': str[str.length] = objectParametize(obj[key], delimeter); } } return (q === true ? '?' : '') + str.join(delimeter); } 

http://jsfiddle.net/userdude/Kk3Lz/2/

 var str = ''; for( var name in obj ) { str += (name + '=' + obj[name] + '&'); } str = str.slice(0,-1); 

给这个一个镜头。

例如: http : //jsfiddle.net/T2UWT/

你可以使用jQuery的param方法:

 var obj = { param1: 'something', param2: 'somethingelse', param3: 'another' } obj['param4'] = 'yetanother'; var str = jQuery.param(obj); alert(str); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 Object.toparams = function ObjecttoParams(obj) { var p = []; for (var key in obj) { p.push(key + '=' + encodeURIComponent(obj[key])); } return p.join('&'); }; 

如果你需要一个recursion函数,根据给定的对象产生正确的URL参数,请试试我的Coffee-Script之一。

 @toParams = (params) -> pairs = [] do proc = (object=params, prefix=null) -> for own key, value of object if value instanceof Array for el, i in value proc(el, if prefix? then "#{prefix}[#{key}][]" else "#{key}[]") else if value instanceof Object if prefix? prefix += "[#{key}]" else prefix = key proc(value, prefix) else pairs.push(if prefix? then "#{prefix}[#{key}]=#{value}" else "#{key}=#{value}") pairs.join('&') 

或编译的JavaScript …

 toParams = function(params) { var pairs, proc; pairs = []; (proc = function(object, prefix) { var el, i, key, value, _results; if (object == null) object = params; if (prefix == null) prefix = null; _results = []; for (key in object) { if (!__hasProp.call(object, key)) continue; value = object[key]; if (value instanceof Array) { _results.push((function() { var _len, _results2; _results2 = []; for (i = 0, _len = value.length; i < _len; i++) { el = value[i]; _results2.push(proc(el, prefix != null ? "" + prefix + "[" + key + "][]" : "" + key + "[]")); } return _results2; })()); } else if (value instanceof Object) { if (prefix != null) { prefix += "[" + key + "]"; } else { prefix = key; } _results.push(proc(value, prefix)); } else { _results.push(pairs.push(prefix != null ? "" + prefix + "[" + key + "]=" + value : "" + key + "=" + value)); } } return _results; })(); return pairs.join('&'); }; 

这将构build像这样的string:

 toParams({a: 'one', b: 'two', c: {x: 'eight', y: ['g','h','j'], z: {asdf: 'fdsa'}}}) "a=one&b=two&c[x]=eight&c[y][0]=g&c[y][1]=h&c[y][2]=j&c[y][z][asdf]=fdsa" 

function性的方法。

 var kvToParam = R.mapObjIndexed((val, key) => { return '&' + key + '=' + encodeURIComponent(val); }); var objToParams = R.compose( R.replace(/^&/, '?'), R.join(''), R.values, kvToParam ); var o = { username: 'sloughfeg9', password: 'traveller' }; console.log(objToParams(o)); 
 <script src="ajax/libs/ramda/0.22.1/ramda.min.js"></script> 

这个方法使用recursion下降到对象层次结构中,并生成轨道解释为embedded哈希的轨道样式参数。 objToParams在最后生成一个带有额外&的查询string,objToQuery删除最后的&lt;

  function objToQuery(obj){ let str = objToParams(obj,''); return str.slice(0, str.length); } function objToParams(obj, subobj){ let str = ""; for (let key in obj) { if(typeof(obj[key]) === 'object') { if(subobj){ str += objToParams(obj[key], `${subobj}[${key}]`); } else { str += objToParams(obj[key], `[${key}]`); } } else { if(subobj){ str += `${key}${subobj}=${obj[key]}&`; }else{ str += `${key}=${obj[key]}&`; } } } return str; }