Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I stringify a JSON object with a negative zero in JavaScript?

How can I use JSON.stringify to convert a negative zero into a string (-0)? It appears that JSON.stringify converts a negative zero into a string representing a positive one. Any idea for a nice workaround?

var jsn = {
    negative: -0
};
isNegative(jsn.negative) ? document.write("negative") : document.write("positive");
var jsonString = JSON.stringify(jsn),
    anotherJSON = JSON.parse(jsonString);
isNegative(anotherJSON.negative) ? document.write("negative") : document.write("positive");

function isNegative(a)
{
    if (0 !== a)
    {
        return !1;
    }
    var b = Object.freeze(
    {
        z: -0
    });
    try
    {
        Object.defineProperty(b, "z",
        {
            value: a
        });
    }
    catch (c)
    {
        return !1;
    }
    return !0;
}
like image 750
Lukasz Ciastko Avatar asked Oct 24 '13 21:10

Lukasz Ciastko


1 Answers

You can write a replacer and a reviver function, for JSON.stringify and JSON.parse, respectively. The replacer can utilize that -0 === 0, 1 / 0 === Infinity and 1 / -0 === -Infinity to identify negative zeros and convert them to a special string. The reviver should simply convert the special string back to -0. Here is the jsfiddle.

The code:

function negZeroReplacer(key, value) {
    if (value === 0 && 1 / value < 0) 
        return "NEGATIVE_ZERO";
    return value;
}

function negZeroReviver(key, value) {
    if (value === "NEGATIVE_ZERO")
        return -0;
    return value;
}

var a = { 
        plusZero: 0, 
        minusZero: -0
    },
    s = JSON.stringify(a, negZeroReplacer),
    b = JSON.parse(s, negZeroReviver);

console.clear();
console.log(a, 1 / a.plusZero, 1 / a.minusZero)
console.log(s);
console.log(b, 1 / b.plusZero, 1 / b.minusZero);

Output:

Object {plusZero: 0, minusZero: 0} Infinity -Infinity
{"plusZero":0,"minusZero":"NEGATIVE_ZERO"} 
Object {plusZero: 0, minusZero: 0} Infinity -Infinity

I converted negative zeros to "NEGATIVE_ZERO", but you can use any other string, like "(-0)".

like image 101
kol Avatar answered Oct 01 '22 16:10

kol