web-dev-qa-db-fra.com

Masquer certaines valeurs dans les sorties de JSON.stringify ()

Est-il possible d'exclure certains champs de l'inclusion dans la chaîne json?

Voici du pseudo code

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

Je veux exclure privateProperty1 et privateproperty2 de la chaîne json

Alors j'ai pensé, je peux utiliser la fonction stringify replacer

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

et dans le stringify

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

Mais dans le jsonString je le vois toujours comme

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

Je voudrais la chaîne sans les propriétés privées en eux.

73
Nilesh

Les Mozilla docs say to return undefined (au lieu de "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));

Voici une méthode de duplication, au cas où vous décidiez de suivre cette voie (selon votre commentaire).

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 - J'ai changé la touche de fonction dans la fonction inférieure pour éviter toute confusion.

79
Jared Farrish

Une autre bonne solution: (nécessite un trait de soulignement)

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

L'avantage de cette solution est que toute personne appelant JSON.stringify sur x obtiendra des résultats corrects - vous ne devez pas modifier les appels JSON.stringify individuellement.

Version non soulignée:

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

Vous pouvez utiliser la fonction native 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}
13
Miroslaw Dylag

Manière plus facile à faire. 

  1. Créez une variable et affectez un tableau vide. Cela fait que l’objet soit le prototype du tableau. 
  2. Ajoutez des clés non numériques sur cet objet. 
  3. Sérialiser cet objet à l'aide de JSON.stringify
  4. Vous verrez que rien n'est sérialisé à partir de cet objet. 

~~~

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

3
Markandey Singh

Object.create est une autre solution proche de la solution defineProperty (les propriétés sont définies de la même manière), mais vous définissez ainsi les propriétés à exposer depuis le début . Ainsi, vous ne pouvez exposer que les propriétés vouloir en définissant la propriété enumerable valeur sur true (false par défaut), JSON.stringify ignore les propriétés non énumérables, mais cette propriété sera également masquée lors de l'utilisation de la boucle for-in sur l'objet ou des fonctions telles que 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"}"
2
Matan Hafuta

Note pour answer de Miroslaw Dylag : La propriété définie doit être sa propre propriété. Sinon, cela échouerait.

Ne fonctionne pas:

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)

Travaux:

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)
1
Audi Nugraha

Je sais que vous avez déjà répondu à cette question, mais j'aimerais ajouter quelque chose lorsque vous utilisez des objets instatiés.

Si vous l'assignez à l'aide d'une fonction, elle ne sera pas incluse dans le résultat JSON.stringify ().

Pour accéder à la valeur, appelez-la également en tant que fonction, terminant par ()

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

Vous pouvez également jouer avec le concept même lorsque vous ne vous trouvez pas sur des objets instatiés.

0
dragonjet

J'ai utilisé la solution toJSON basée sur une petite bibliothèque que j'ai écrite afin d'obtenir Taper à l'exécution https://stackoverflow.com/a/55917109/4236151

0
Yacine
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;
    };
}
0

vous pouvez le faire facilement avec ES2017

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

Ici privateProperty1 et privateProperty2 sont affectés à exc1 et exc2 en conséquence. Les restants sont affectés à la variable foo nouvellement créée 

0
peja