Скрыть определенные значения в выводе из JSON.stringify () - PullRequest
76 голосов
/ 06 февраля 2011

Можно ли исключить определенные поля из включения в строку json?

Вот какой-то псевдокод

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

Я хочу исключить privateProperty1 и privateproperty2 из появления в jsonstring

Итак, я подумал, что могу использовать функцию заменителя 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 }

Я бы хотел, чтобы в строке не было частных свойств.

Ответы [ 10 ]

86 голосов
/ 06 февраля 2011

Документы 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'])));

РЕДАКТИРОВАТЬ - Я изменил функциональную клавишу в нижней функции, чтобы она не путалась.

24 голосов
/ 01 февраля 2016

Другое хорошее решение: (требует подчеркивания)

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

Преимущество этого решения в том, что любой, кто вызывает JSON.stringify для x, будет иметь правильные результаты - вам не нужно изменять JSON.stringifyзвонки индивидуально.

Версия без подчеркивания:

x.toJSON = function () {
    var result = {};
    for (var x in this) {
        if (x !== "privateProperty1" && x !== "privateProperty2") {
            result[x] = this[x];
        }
    }
    return result;
};
14 голосов
/ 20 января 2016

Вы можете использовать встроенную функцию defineProperty из объекта:

var data = {a: 10};
Object.defineProperty(data, 'transient', {value: 'static', writable: true});
data.transient = 'dasda';
console.log(JSON.stringify(data)); //{"a":10}
3 голосов
/ 19 июля 2015

Более простой способ сделать.

  1. Создайте переменную и назначьте пустой массив. Это делает объект прототипом массива.
  2. Добавить нечисловые ключи для этого объекта.
  3. Сериализация этого объекта с использованием JSON.stringify
  4. Вы увидите, что ничего не сериализовано из этого объекта.

~~~ * * 1013

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 голосов
/ 10 сентября 2016

Object.create - это другое решение, близкое к решению defineProperty (свойства определяются аналогичным образом), но таким образом вы определяете свойства, которые будут предоставлены с самого начала.Таким образом, вы можете выставить только те свойства, которые вам нужны, установив для свойства enumerable value значение 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"}"
1 голос
/ 30 августа 2017

Примечание для Miroslaw Dylag 's answer : определенное свойство должно быть собственным Иначе это не получится.

Не работает:

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)
0 голосов
/ 30 апреля 2019

Я использовал решение toJSON, основанное на небольшой библиотеке, которую я написал, чтобы набирать текст во время выполнения https://stackoverflow.com/a/55917109/4236151

0 голосов
/ 18 июля 2018

Вы можете сделать это легко с ES2017

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

Здесь privateProperty1 и privateProperty2 назначены exc1 и exc2 соответственно. Остатки присваиваются foo вновь созданной переменной

0 голосов
/ 18 марта 2018
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 голосов
/ 18 июня 2015

Я знаю, что это уже ответ на вопрос, но я хотел бы кое-что добавить при использовании объектов на основе.

Если вы назначите его с помощью функции, он не будет включен в результат 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

Вы также можете поиграть с концепцией, даже если не на объектах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...