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.
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.
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;
};
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}
Manière plus facile à faire.
~~~
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 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"}"
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)
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.
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
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;
};
}
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