Скрыть определенные значения на выходе из JSON.stringify()
Можно ли исключить определенные поля из строки json?
Вот несколько псевдокодов
var x = {
x:0,
y:0,
divID:"xyz",
privateProperty1: 'foo',
privateProperty2: 'bar'
}
Я хочу, чтобы privateProperty1 и privateproperty2 отображались в строке json
Итак, я подумал, я могу использовать функцию replicate для 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 в них.
Ответы
Ответ 1
Документы 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'])));
РЕДАКТИРОВАТЬ - Я изменил функциональную клавишу в нижней функции, чтобы избежать путаницы.
Ответ 2
Другое хорошее решение: (требуется подчеркнуть)
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;
};
Ответ 3
Вы можете использовать собственную функцию defineProperty из Object:
var data = {a: 10};
Object.defineProperty(data, 'transient', {value: 'static', writable: true});
data.transient = 'dasda';
console.log(JSON.stringify(data)); //{"a":10}
Ответ 4
Простой способ сделать.
- Создайте переменную и назначьте пустой массив. Это делает объект прототипом массива.
- Добавьте к этому объекту нецифровые ключи.
- Сериализовать этот объект с помощью JSON.stringify
- Вы увидите, что из этого объекта ничего не сериализуется.
~~~
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
Ответ 5
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"}"
Ответ 6
Примечание для Мирослав Дилаг 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)
Ответ 7
Я знаю, что это уже ответ на вопрос, но я хотел бы добавить что-то при использовании объектов с установкой.
Если вы назначили его с помощью функции, он не будет включен в результат 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
Вы также можете играть с концепцией, даже если не на объектах с установленными объектами.
Ответ 8
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;
};
}
Ответ 9
Вы можете сделать это легко с ES2017
let {privateProperty1:exc1, privateProperty2:exc2, ...foo} = {
x:0,
y:0,
divID:"xyz",
privateProperty1: 'foo',
privateProperty2: 'bar'
}
Здесь privateProperty1
и privateProperty2
назначаются для exc1
и exc2
соответственно. Остатки присваиваются вновь созданной переменной foo
Ответ 10
Я использовал решение toJSON, основанное на небольшой библиотеке, которую я написал, чтобы набирать текст во время выполнения fooobar.com/info/1011374/...