在不知道JavaScript对象的键的情况下,我如何将…

var obj = {
   param1: 'something',
   param2: 'somethingelse',
   param3: 'another'
}

obj[param4] = 'yetanother';

…到…

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

...?


当前回答

我需要处理嵌套对象和数组的东西。

const Util = {
  isArray: function(val) {
    return Object.prototype.toString.call(val) === '[object Array]';
  },
  isNil: function(val) {
    return val === null || Util.typeOf(val)
  },
  typeOf: function(val, type) {
    return (type || 'undefined') === typeof val;
  },
  funEach: function(obj, fun) {
    if (Util.isNil(obj))
      return;      // empty value

    if (!Util.typeOf(obj, 'object'))
      obj = [obj]; // Convert to array

    if (Util.isArray(obj)) {
      // Iterate over array
      for (var i = 0, l = obj.length; i < l; i++)
        fun.call(null, obj[i], i, obj);
    } else {
      // Iterate over object
      for (var key in obj)
        Object.prototype.hasOwnProperty.call(obj, key) && fun.call(null, obj[key], key, obj);
    }
  }
};

const serialize = (params) => {
  let pair = [];

  const encodeValue = v => {
    if (Util.typeOf(v, 'object'))
      v = JSON.stringify(v);

    return encodeURIComponent(v);
  };

  Util.funEach(params, (val, key) => {
    let isNil = Util.isNil(val);

    if (!isNil && Util.isArray(val))
      key = `${key}[]`;
    else
      val = [val];

    Util.funEach(val, v => {
      pair.push(`${key}=${isNil ? "" : encodeValue(v)}`);
    });
  });

  return pair.join('&');
};

用法:

serialize({
  id: null,
  lat: "27",
  lng: "53",
  polygon: ["27,53", "31,18", "22,62", "..."]
}); // "id=&lat=27&lng=53&polygon[]=27%2C53&polygon[]=31%2C18&polygon[]=22%2C62&polygon[]=..."

其他回答

在一层深处…

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。

有关于任意深度对象的递归函数的讨论……

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()。

如果你需要一个递归函数来根据给定的对象生成正确的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('&');
};

这将构造如下的字符串:

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"

我需要处理嵌套对象和数组的东西。

const Util = {
  isArray: function(val) {
    return Object.prototype.toString.call(val) === '[object Array]';
  },
  isNil: function(val) {
    return val === null || Util.typeOf(val)
  },
  typeOf: function(val, type) {
    return (type || 'undefined') === typeof val;
  },
  funEach: function(obj, fun) {
    if (Util.isNil(obj))
      return;      // empty value

    if (!Util.typeOf(obj, 'object'))
      obj = [obj]; // Convert to array

    if (Util.isArray(obj)) {
      // Iterate over array
      for (var i = 0, l = obj.length; i < l; i++)
        fun.call(null, obj[i], i, obj);
    } else {
      // Iterate over object
      for (var key in obj)
        Object.prototype.hasOwnProperty.call(obj, key) && fun.call(null, obj[key], key, obj);
    }
  }
};

const serialize = (params) => {
  let pair = [];

  const encodeValue = v => {
    if (Util.typeOf(v, 'object'))
      v = JSON.stringify(v);

    return encodeURIComponent(v);
  };

  Util.funEach(params, (val, key) => {
    let isNil = Util.isNil(val);

    if (!isNil && Util.isArray(val))
      key = `${key}[]`;
    else
      val = [val];

    Util.funEach(val, v => {
      pair.push(`${key}=${isNil ? "" : encodeValue(v)}`);
    });
  });

  return pair.join('&');
};

用法:

serialize({
  id: null,
  lat: "27",
  lng: "53",
  polygon: ["27,53", "31,18", "22,62", "..."]
}); // "id=&lat=27&lng=53&polygon[]=27%2C53&polygon[]=31%2C18&polygon[]=22%2C62&polygon[]=..."

const obj = { id: 1, name: 'Neel' }; 设 str = ''; str = Object.entries(obj).map(([key, val]) => '${key}=${val}').join('&'); console.log(str);

试试这个…这也适用于嵌套对象。

let my_obj = {'single':'this is single', 'nested':['child1','child2']};

((o)=>{ return Object.keys(o).map(function(key){ let ret=[]; if(Array.isArray(o[key])){ o[key].forEach((item)=>{ ret.push(`${key}[]=${encodeURIComponent(item)}`); }); }else{ ret.push(`${key}=${encodeURIComponent(o[key])}`); } return ret.join("&");  }).join("&"); })(my_obj);