我可以使一个JSON字符串化的对象有一个在Javascript中值为double的字段吗?

时间:2015-10-13 22:36:31

标签: javascript json

我正在将JSON从我的Javascript应用程序发布到此API,如果您将它发送给双打,则会有不同的行为。我只是使用JSON.stringify来构建我的请求主体。我总是想送双打。但是当我有Javascript数字是不可或缺的时候,JSON.stringify会这样做:

> JSON.stringify({x: 1.0});
'{"x":1}'

那个朴实无华的1进入API,其他服务器认为它是一个int,我得到整数行为,我不想要。是否有任何已知的黑客在Javascript中使用我的JSON加倍?

3 个答案:

答案 0 :(得分:1)

JSON(以及一般的JavaScript)不区分不同的数字类型;只有"数字"。因此,这有点超出了JSON.stringify的范围。

这是一个非常糟糕的解决方法:

JSON.stringify({x: 1.0}).replace(
    /("(?:[^"\\]|\\.)*")|[\[:,]\s*-?\d+(?![\d.eE])/g,
    function (m0, m1) { return m1 || m0 + '.0'; }
)

这个(相当大的锤子)使用正则表达式将.0添加到所有不具有.并且不属于带引号的字符串的数字中。

答案 1 :(得分:1)

另一种方法:构建JSON.stringify的自定义版本,它将始终输出带小数点的数字。

这只是从Mozilla JSON documentation获取一个示例实现,并修改处理数字的代码行:

window.JSON.stringifyDecimal = (function(){
  var toString = Object.prototype.toString;
  var isArray = Array.isArray || function (a) { return toString.call(a) === '[object Array]'; };
  var escMap = {'"': '\\"', '\\': '\\\\', '\b': '\\b', '\f': '\\f', '\n': '\\n', '\r': '\\r', '\t': '\\t'};
  var escFunc = function (m) { return escMap[m] || '\\u' + (m.charCodeAt(0) + 0x10000).toString(16).substr(1); };
  var escRE = /[\\"\u0000-\u001F\u2028\u2029]/g;
  return function stringify(value) {
    if (value == null) {
      return 'null';
    } else if (typeof value === 'number') {

      // Ensure decimal point is present
      return isFinite(value) ? value.toString() + ( Number.isInteger( value ) ? '.0' : '' ) : 'null';

    } else if (typeof value === 'boolean') {
      return value.toString();
    } else if (typeof value === 'object') {
      if (typeof value.toJSON === 'function') {
        return stringify(value.toJSON());
      } else if (isArray(value)) {
        var res = '[';
        for (var i = 0; i < value.length; i++)
          res += (i ? ', ' : '') + stringify(value[i]);
        return res + ']';
      } else if (toString.call(value) === '[object Object]') {
        var tmp = [];
        for (var k in value) {
          if (value.hasOwnProperty(k))
            tmp.push(stringify(k) + ': ' + stringify(value[k]));
        }
        return '{' + tmp.join(', ') + '}';
      }
    }
    return '"' + value.toString().replace(escRE, escFunc) + '"';
  };
})();

答案 2 :(得分:0)

使用JSON,您有两个派对:作者和读者。在您的情况下,作者是您的请求,您正在使用JSON.stringify生成JSON字符串,而读者是API(我不知道它用于解析字符串的内容到JSON对象)。您需要双方都能够理解1.0应保持原样,因为它是双精度而不是整数。

JSON字符串本身只是文本,并保留您给它的任何内容。将JSON.stringify转换为1.0的是1,因此您可以轻松地手动创建JSON字符串,而不是使用JSON.stringify

var text = JSON.stringify({x: 1.0}); //JSON string will be {"x": 1}
var text = '{"x": 1.0}'; //JSON string will be exactly {"x": 1.0}

但是,即使您这样做,也需要另一方(即API)将值1.0解析为double,而不是整数。这是你的控制吗?例如,JavaScript JSON.parse函数会将1.0解析为1,与JSON.stringify完全相同:

var obj = JSON.parse('{"x": 1.0}');
alert(obj.x); //It prints 1, even though we gave it 1.0