Hide certain values in output from JSON.stringify()

Is it possible to exclude certain fields from being included in the json string?

Here is some pseudo code

var x = {
    x:0,
    y:0,
    divID:"xyz",
    privateProperty1: 'foo',
    privateProperty2: 'bar'
}

I want to exclude privateProperty1 and privateproperty2 from appearing in the json string

So I thought, I can use the stringify replacer function

function replacer(key,value)
{
    if (key=="privateProperty1") then retun "none";
    else if (key=="privateProperty2") then retun "none";
    else return value;
}

and in the stringify

var jsonString = json.stringify(x,replacer);

But in the jsonString I still see it as

{...privateProperty1:value..., privateProperty2:value }

I would like to the string without the privateproperties in them.


The Mozilla docs say to return undefined (instead of "none"):

http://jsfiddle.net/userdude/rZ5Px/

function replacer(key,value)
{
    if (key=="privateProperty1") return undefined;
    else if (key=="privateProperty2") return undefined;
    else return value;
}

var x = {
    x:0,
    y:0,
    divID:"xyz",
    privateProperty1: 'foo',
    privateProperty2: 'bar'
};

alert(JSON.stringify(x, replacer));

Here is a duplication method, in case you decide to go that route (as per your comment).

http://jsfiddle.net/userdude/644sJ/

function omitKeys(obj, keys)
{
    var dup = {};
    for (var key in obj) {
        if (keys.indexOf(key) == -1) {
            dup[key] = obj[key];
        }
    }
    return dup;
}

var x = {
    x:0,
    y:0,
    divID:"xyz",
    privateProperty1: 'foo',
    privateProperty2: 'bar'
};

alert(JSON.stringify(omitKeys(x, ['privateProperty1','privateProperty2'])));

EDIT - I changed the function key in the bottom function to keep it from being confusing.


Another good solution: (requires underscore)

x.toJSON = function () {
    return _.omit(this, [ "privateProperty1", "privateProperty2" ]);
};

The benefit of this solution is that anyone calling JSON.stringify on x will have correct results - you don't have to alter the JSON.stringify calls individually.

Non-underscore version:

x.toJSON = function () {
    var result = {};
    for (var x in this) {
        if (x !== "privateProperty1" && x !== "privateProperty2") {
            result[x] = this[x];
        }
    }
    return result;
};

You can use native function defineProperty from Object:

var data = {a: 10};
Object.defineProperty(data, 'transient', {value: 'static', writable: true});
data.transient = 'dasda';
console.log(JSON.stringify(data)); //{"a":10}