admin管理员组

文章数量:1134557

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.

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.

Share Improve this question edited Dec 13, 2016 at 8:44 Evan Carroll 1 asked Feb 6, 2011 at 0:01 NileshNilesh 2,1153 gold badges19 silver badges21 bronze badges 4
  • Possible duplicate: stackoverflow.com/questions/208105/… – Jared Farrish Commented Feb 6, 2011 at 0:07
  • 5 instead of returning "none" return undefined. – JoeyRobichaud Commented Feb 6, 2011 at 0:09
  • 1 I saw that question and I don't want to delete properties as it affects my current application. I am trying to save the object to a file and the application still has the live object so deleting a property will make it useless. Another option is I could clone the object, delete fields and then stringify the clone object. – Nilesh Commented Feb 6, 2011 at 0:10
  • 1 Hey Joe, that was great. The undefined did the trick. Thanks. I will update the question – Nilesh Commented Feb 6, 2011 at 0:28
Add a comment  | 

16 Answers 16

Reset to default 147

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}

This is an old question, but I'm adding an answer as there is a much simpler way to deal with this. Pass an array of strings that you wish to output in the JSON.

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

JSON.stringify(x, ["x", "y", "divID"]);

// This will output only x y and divID
// {"x":0,"y":0,"divID":"xyz"}

Here is my approach with the spread operator (...) :

const obj = {
  name: "hello",
  age: 42,
  id: "3942"
};

const objWithoutId = { ...obj, id: undefined };

const jsonWithoutId = JSON.stringify(objWithoutId);

console.log(jsonWithoutId);

I know this is already an answered question, but I'd like to add something when using instatiated objects.

If you assign it using a function, it will not be included on the JSON.stringify() result.

To access the value, call it as a function as well, ending with ()

var MyClass = function(){
    this.visibleProperty1 = "sample1";
    this.hiddenProperty1 = function(){ return "sample2" };
}

MyClass.prototype.assignAnother = function(){
    this.visibleProperty2 = "sample3";
    this.visibleProperty3 = "sample4";
    this.hiddenProperty2 = function(){ return "sample5" };
}

var newObj = new MyClass();
console.log( JSON.stringify(newObj) );
// {"visibleProperty1":"sample1"}

newObj.assignAnother();
console.log( JSON.stringify(newObj) );
// {"visibleProperty1":"sample1","visibleProperty2":"sample3","visibleProperty3":"sample4"}

console.log( newObj.visibleProperty2 ); // sample3
console.log( newObj.hiddenProperty1() ); // sample2
console.log( newObj.hiddenProperty2() ); // sample5

You can also play around with the concept even when not on instatiated objects.

Easier way to do.

  1. Create a variable and assign an empty array. This makes object to be the prototype of array.
  2. Add non numeric keys on this object.
  3. Serialize this object using JSON.stringify
  4. You will see that nothing is serialized from this object.

~~~

var myobject={
  a:10,
  b:[]
};

myobject.b.hidden1 = 'hiddenValue1';
myobject.b.hidden2 = 'hiddenValue2';

//output of stringify 
//{
//    "a": 10,
//    "b": []
//}

~~~

http://www.markandey.com/2015/07/how-to-hide-few-keys-from-being-being.html

Object.create is another solution that is close to the defineProperty solution (properties are defined in the same way) but in this way you define the properties to expose from the beginning. In this way you can expose only the properties that you want by setting the property enumerable value to true (false by default), JSON.stringify is ignoring non-enumerable properties, the downside is that this property will also be hidden when using for-in loop on the object or functions like Object.keys.

var x = Object.create(null, {
    x: {value:0, enumerable: true}, 
    y:{value: 0, enumerable: true}, 
    divID: {value: 'xyz', enumerable: true}, 
    privateProperty1: {value: 'foo'}, 
    privateProperty2: {value: 'bar'}
});
JSON.stringify(x)
//"{"x":0,"y":0,"divID":"xyz"}"

Note for Miroslaw Dylag's answer: The defined property should be its own property. Otherwise it would fail.

Doesn't work:

class Foo {
}
Object.defineProperty(Foo.prototype, 'bar', { value: 'bar', writable: true });

const foo = new Foo();
foo.bar = 'baz';
alert(JSON.stringify(foo).indexOf('bar') === -1); // false (found)

Works:

class Foo {
  constructor() {
    Object.defineProperty(this, 'bar', { value: 'bar', writable: true });
  }
}

const foo = new Foo();
foo.bar = 'baz';
alert(JSON.stringify(foo).indexOf('bar') === -1); // true (not found)
abstract class Hideable {
    public hidden = [];
    public toJSON() {
        var result = {};
        for (var x in this) {
            if(x == "hidden") continue;
            if (this.hidden.indexOf(x) === -1) {
                result[x] = this[x];
            }
        }
        return result;
    };
}

Here's another approach, although without Internet Explorer support.

const privateProperties = ["privateProperty1", "privateProperty2"];
const excludePrivateProperties = (key, value) => privateProperties.includes(key) ? undefined : value;

const jsonString = JSON.stringify(x, excludePrivateProperties);

you can do it easily with ES2017

let {privateProperty1:exc1, privateProperty2:exc2, ...foo} = {
    x:0,
    y:0,
    divID:"xyz",
    privateProperty1: 'foo',
    privateProperty2: 'bar'
}

Here privateProperty1 and privateProperty2 are assigned to exc1 and exc2 accordingly. The remainings are assigned to foo newly created variable

I've used toJSON solution based on a small library that i've written in order to get Typing at Runtime https://stackoverflow.com/a/55917109/4236151

I subscribe to delp's Topic https://stackoverflow.com/a/62457745/14491024 This topic helped with my code

 JSON.stringify(GetMyContent[i], ["mdlPageName", "mdlAligen", "mdlOrderNumberHorizontal", "mdlPageId", "mdlOrderNumberVertical"])

That way I can pick attributes that I need:

    if (GetMyContent[i].mdlAligen == "Left") {

        var getrownum = GetMyContent[i].mdlOrderNumberHorizontal;

        if ($('.Left div.row:eq(' + (getrownum - 1) + ')').children().length > 0) {

            $('.Left div.row:eq(' + (getrownum - 1) + ')').append("<div id=" + GetMyContent[i].mdlPageId + " class=\"border border-secondary col\"  " + "data-atrrib=" + JSON.stringify(GetMyContent[i], ["mdlPageName", "mdlAligen", "mdlOrderNumberHorizontal", "mdlPageId", "mdlOrderNumberVertical"]) + ">" + GetMyContent[i].mdlPageContentHtml + buttonEDI + "</div>");
        }
        else {
            $('.Left div.row:last').html("<div id=" + GetMyContent[i].mdlPageId + " class=\"border border-secondary col\"  " + "data-atrrib=" + JSON.stringify(GetMyContent[i], ["mdlPageName", "mdlAligen", "mdlOrderNumberHorizontal", "mdlPageId", "mdlOrderNumberVertical"]) + ">" + GetMyContent[i].mdlPageContentHtml + buttonEDI + "</div>");

                $(".Left .row:last").after($('.Left .row:eq(0)').clone().html(""));
        }
    }

In addition to toJSON and replacers. A simple fix would be to convert the variable to a 'static' variable. Since the static variables are added as prototype variables they won't come in the JSON string.

Caution: Please use this if the variable can be a static variable.

removes is an array of keys you want to omit. space is optional for pretty printing.

// typescript version
export function toJson<T>(me: T, removes?: (keyof T)[], space?: number): string {
  return JSON.stringify(me, (k, v) => (removes?.some((r) => r === k) ? undefined : v), space);
}

// javascript version
export function toJson(me , removes , space) {
  return JSON.stringify(me, (k, v) => (removes?.some((r) => r === k) ? undefined : v), space);
}

example

const data = {name: "ali" ,age: "80"};
console.log(toJson(data, ["age"]))

// output: {"name":"ali"}

本文标签: javascriptHide certain values in output from JSONstringify()Stack Overflow