JSON.stringify()からの出力で特定の値を非表示にします


86

特定のフィールドをjson文字列に含めることから除外することは可能ですか?

ここにいくつかの擬似コードがあります

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

privateProperty1とprivateproperty2をjson文字列に表示しないようにしたい

だから私はstringify置換機能を使うことができると思いました

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

とstringifyで

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

しかし、jsonStringではまだそれを次のように見ています

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

privatepropertiesを含まない文字列を作成したいと思います。



4
「none」を返す代わりに、undefinedを返します。
JoeyRobichaud 2011

1
その質問を見ましたが、現在のアプリケーションに影響するため、プロパティを削除したくありません。オブジェクトをファイルに保存しようとしていますが、アプリケーションにはまだライブオブジェクトがあるため、プロパティを削除すると役に立たなくなります。もう1つのオプションは、オブジェクトのクローンを作成し、フィールドを削除してから、クローンオブジェクトを文字列化することです。
ナイルシュ2011

1
ヘイジョー、それは素晴らしかった。未定義がトリックをしました。ありがとう。質問を更新します
Nilesh 2011

回答:


100

Mozillaのドキュメントを返すように言うundefined(の代わりに"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));

あなたがそのルートに行くことにした場合の複製方法はここにあります(あなたのコメントによると)。

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

編集-混乱しないように、下部の関数のファンクションキーを変更しました。


33

別の良い解決策:(アンダースコアが必要)

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

このソリューションの利点は、xでJSON.stringifyを呼び出すと、正しい結果が得られることです。JSON.stringifyの呼び出しを個別に変更する必要はありません。

アンダースコアなしのバージョン:

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

Iこのアプローチのための投票を私はそれがよりエレガントであることを見つけるために...
ロミオシエラ

18

Objectからネイティブ関数definePropertyを使用できます。

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

12
このenumerableプロパティ記述子の値がfalseであるため、この回答は機能します。
Soul_Master 2017年

注:データが配列であり、そのn番目の要素を非表示にする場合は機能しません。
アレックスSzücs

3

より簡単な方法。

  1. 変数を作成し、空の配列を割り当てます。これにより、オブジェクトが配列のプロトタイプになります。
  2. このオブジェクトに数値以外のキーを追加します。
  3. JSON.stringifyを使用してこのオブジェクトをシリアル化します
  4. このオブジェクトからは何もシリアル化されていないことがわかります。

~~~

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


2

Object.createは、definePropertyソリューションに近い別のソリューションです(プロパティは同じ方法で定義されます)が、この方法で、最初から公開するプロパティを定義します。このように、プロパティenumerable値をtrue(デフォルトではfalse)に設定することで、必要なプロパティのみを公開できます。JSON.stringifyは列挙できないプロパティを無視します。欠点は、for-inを使用するとこのプロパティも非表示になることです。オブジェクトまたは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

Miroslaw Dylag回答に関する注記:定義されたプロパティはそれ自体のプロパティである必要があります。そうでなければ失敗します。

動作しません:

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)

作品:

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

これはすでに回答済みの質問ですが、インスタンス化されたオブジェクトを使用するときに何かを追加したいと思います。

関数を使用して割り当てる場合、JSON.stringify()の結果には含まれません。

値にアクセスするには、値を関数として呼び出し、最後に ()

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

また、インスタンス化されたオブジェクトを使用していない場合でも、コンセプトを試すことができます。


これは、そのプロパティの値を設定する必要がない場合にのみ機能します。
ガブリエル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;
    };
}

0

ES2017で簡単にできます

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

ここでprivateProperty1privateProperty2に割り当てられexc1exc2それに応じて。残りはfoo新しく作成された変数に割り当てられます



0

Internet Explorerのサポートはありませんが、別のアプローチがあります。

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

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

0

これは古い質問ですが、これに対処するためのはるかに簡単な方法があるので、私は答えを追加しています。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"}


0

これがスプレッド演算子を使った私のアプローチです(...):

const obj = { name:"hello", age:42, id:"3942" };
const objWithoutId = { ...o, id: undefined }

const jsonWithoutId = JSON.stringify({...o, id:undefined});
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.