Verbergen Sie bestimmte Werte in der Ausgabe von JSON.stringify ()

85

Ist es möglich, bestimmte Felder von der Aufnahme in die JSON-Zeichenfolge auszuschließen?

Hier ist ein Pseudocode

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

Ich möchte privateProperty1 und privateproperty2 vom Erscheinen in der JSON-Zeichenfolge ausschließen

Also dachte ich, ich kann die Stringify-Ersetzungsfunktion verwenden

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

und in der stringify

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

Aber im jsonString sehe ich es immer noch als

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

Ich möchte die Zeichenfolge ohne die darin enthaltenen privaten Eigenschaften.

Nilesh
quelle
Mögliches Duplikat: stackoverflow.com/questions/208105/…
Jared Farrish
4
anstatt "none" zurückzugeben, geben Sie undefined zurück.
JoeyRobichaud
1
Ich habe diese Frage gesehen und möchte keine Eigenschaften löschen, da dies Auswirkungen auf meine aktuelle Anwendung hat. Ich versuche, das Objekt in einer Datei zu speichern, und die Anwendung verfügt weiterhin über das Live-Objekt. Wenn Sie also eine Eigenschaft löschen, wird sie unbrauchbar. Eine andere Möglichkeit ist, das Objekt zu klonen, Felder zu löschen und dann das Klonobjekt zu stringifizieren.
Nilesh
1
Hey Joe, das war großartig. Der Undefinierte hat es geschafft. Vielen Dank. Ich werde die Frage aktualisieren
Nilesh

Antworten:

98

Die Mozilla-Dokumente sagen, dass sie undefined(anstelle von "none") zurückkehren sollen:

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));

Hier ist eine Duplizierungsmethode, falls Sie sich für diesen Weg entscheiden (gemäß Ihrem Kommentar).

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'])));

BEARBEITEN - Ich habe die Funktionstaste in der unteren Funktion geändert, um Verwirrung zu vermeiden.

Jared Farrish
quelle
31

Eine weitere gute Lösung: (erfordert Unterstrich)

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

Der Vorteil dieser Lösung besteht darin, dass jeder, der JSON.stringify unter x aufruft, korrekte Ergebnisse erzielt. Sie müssen die JSON.stringify-Aufrufe nicht einzeln ändern.

Nicht unterstrichene Version:

x.toJSON = function () {
    var result = {};
    for (var x in this) {
        if (x !== "privateProperty1" && x !== "privateProperty2") {
            result[x] = this[x];
        }
    }
    return result;
};
Curtis Yallop
quelle
Ich stimme für diesen Ansatz, weil ich ihn eleganter finde.
Romeo Sierra
17

Sie können die native Funktion defineProperty aus Object verwenden:

var data = {a: 10};
Object.defineProperty(data, 'transient', {value: 'static', writable: true});
data.transient = 'dasda';
console.log(JSON.stringify(data)); //{"a":10}
Miroslaw Dylag
quelle
10
Diese Antwort funktioniert, weil der enumerableWert dieses Eigenschaftsdeskriptors falsch ist.
Soul_Master
3

Einfachere Möglichkeit.

  1. Erstellen Sie eine Variable und weisen Sie ein leeres Array zu. Dies macht das Objekt zum Prototyp eines Arrays.
  2. Fügen Sie diesem Objekt nicht numerische Schlüssel hinzu.
  3. Serialisieren Sie dieses Objekt mit JSON.stringify
  4. Sie werden sehen, dass von diesem Objekt nichts serialisiert wird.

~~~

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

Markandey Singh
quelle
2

Object.create ist eine andere Lösung, die der defineProperty-Lösung nahe kommt (Eigenschaften werden auf dieselbe Weise definiert), aber auf diese Weise definieren Sie die Eigenschaften, die von Anfang an verfügbar gemacht werden sollen. Auf diese Weise können Sie nur die gewünschten Eigenschaften enumerableverfügbar machen, indem Sie den Eigenschaftswert auf true setzen (standardmäßig false). JSON.stringify ignoriert nicht aufzählbare Eigenschaften. Der Nachteil ist, dass diese Eigenschaft auch bei Verwendung von for-in ausgeblendet wird Schleife auf dem Objekt oder Funktionen wie 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"}"
Matan Hafuta
quelle
2

Hinweis für Miroslaw Dylag ‚s Antwort : Die definierte Eigenschaft sollte seine eigene Eigenschaft sein. Sonst würde es scheitern.

Funktioniert nicht:

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)

Werke:

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)
Audi Nugraha
quelle
0

Ich weiß, dass dies bereits eine beantwortete Frage ist, aber ich möchte etwas hinzufügen, wenn ich instanziierte Objekte verwende.

Wenn Sie es mit einer Funktion zuweisen, wird es nicht in das Ergebnis von JSON.stringify () aufgenommen.

Um auf den Wert zuzugreifen, rufen Sie ihn ebenfalls als Funktion auf und enden mit ()

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

Sie können auch dann mit dem Konzept herumspielen, wenn es sich nicht um instanziierte Objekte handelt.

Drachenjet
quelle
Dies funktioniert nur, wenn Sie den Wert dieser Eigenschaft nicht festlegen müssen.
Gabriel C
0
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;
    };
}
Carlos Arturo Alaniz
quelle
0

Sie können es einfach mit ES2017 tun

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

Hier haben privateProperty1und privateProperty2sind zu vergeben exc1und sich exc2entsprechend. Die verbleibenden werden einer fooneu erstellten Variablen zugewiesen

Peja
quelle
0

Ich habe die JSON-Lösung verwendet, die auf einer kleinen Bibliothek basiert, die ich geschrieben habe, um das Schreiben zur Laufzeit zu erhalten. Https://stackoverflow.com/a/55917109/4236151

Yacine
quelle
0

Hier ist ein anderer Ansatz, allerdings ohne Internet Explorer-Unterstützung.

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

const jsonString = JSON.stringify(x, excludePrivateProperties);
Mike Nikles
quelle
0

Dies ist eine alte Frage, aber ich füge eine Antwort hinzu, da es einen viel einfacheren Weg gibt, damit umzugehen. Übergeben Sie ein Array von Zeichenfolgen, die Sie in JSON ausgeben möchten.

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"}

delp
quelle