É possível excluir certos campos de serem incluídos na string json?
Aqui está um pseudo código
var x = {
x:0,
y:0,
divID:"xyz",
privateProperty1: 'foo',
privateProperty2: 'bar'
}
Eu quero excluir privateProperty1 e privateproperty2 de aparecerem na string json
Então pensei, posso usar a função substituidor de stringify
function replacer(key,value)
{
if (key=="privateProperty1") then retun "none";
else if (key=="privateProperty2") then retun "none";
else return value;
}
e no stringify
var jsonString = json.stringify(x,replacer);
Mas no jsonString ainda vejo como
{...privateProperty1:value..., privateProperty2:value }
Eu gostaria da string sem as propriedades privadas nelas.
javascript
json
Nilesh
fonte
fonte
Respostas:
Os documentos do Mozilla dizem para retornar
undefined
(em vez 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));
Aqui está um método de duplicação, caso você decida seguir esse caminho (conforme seu comentário).
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 - eu mudei a tecla de função na função inferior para evitar que seja confuso.
fonte
Outra boa solução: (requer sublinhado)
x.toJSON = function () { return _.omit(this, [ "privateProperty1", "privateProperty2" ]); };
O benefício dessa solução é que qualquer pessoa que chamar JSON.stringify em x terá resultados corretos - você não precisa alterar as chamadas JSON.stringify individualmente.
Versão sem sublinhado:
x.toJSON = function () { var result = {}; for (var x in this) { if (x !== "privateProperty1" && x !== "privateProperty2") { result[x] = this[x]; } } return result; };
fonte
Você pode usar a função nativa defineProperty de Object:
var data = {a: 10}; Object.defineProperty(data, 'transient', {value: 'static', writable: true}); data.transient = 'dasda'; console.log(JSON.stringify(data)); //{"a":10}
fonte
enumerable
valor desse descritor de propriedade é falso.Maneira mais fácil de fazer.
~~~
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
fonte
Object.create é outra solução próxima da solução defineProperty (as propriedades são definidas da mesma maneira), mas dessa forma você define as propriedades a serem expostas desde o início. Desta forma, você pode expor apenas as propriedades que deseja definindo o
enumerable
valor da propriedade como verdadeiro (falso por padrão), JSON.stringify está ignorando propriedades não enumeráveis, a desvantagem é que essa propriedade também ficará oculta ao usar for-in loop no objeto ou funções como 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"}"
fonte
Nota para a resposta de Miroslaw Dylag : A propriedade definida deve ser sua própria propriedade. Caso contrário, iria falhar.
Não funciona:
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)
Trabalho:
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)
fonte
Eu sei que esta já é uma questão respondida, mas gostaria de acrescentar algo ao usar objetos instatados.
Se você atribuí-lo usando uma função, ele não será incluído no resultado JSON.stringify ().
Para acessar o valor, chame-o também como uma função, terminando com
()
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
Você também pode brincar com o conceito, mesmo quando não estiver em objetos instatados.
fonte
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; }; }
fonte
você pode fazer isso facilmente com ES2017
let {privateProperty1:exc1, privateProperty2:exc2, ...foo} = { x:0, y:0, divID:"xyz", privateProperty1: 'foo', privateProperty2: 'bar' }
Aqui
privateProperty1
eprivateProperty2
são atribuídosexc1
e emexc2
conformidade. O restante é atribuído a umafoo
variável recém-criadafonte
Eu usei a solução toJSON com base em uma pequena biblioteca que escrevi para obter a digitação em tempo de execução https://stackoverflow.com/a/55917109/4236151
fonte
Aqui está outra abordagem, embora sem suporte do Internet Explorer.
const privateProperties = ["privateProperty1", "privateProperty2"]; const excludePrivateProperties = (key, value) => privateProperties.includes(key) ? undefined : value; const jsonString = JSON.stringify(x, excludePrivateProperties);
fonte
Esta é uma pergunta antiga, mas estou adicionando uma resposta, pois há uma maneira muito mais simples de lidar com isso. Passe uma matriz de strings que você deseja produzir no 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"}
fonte
Aqui está minha abordagem com o operador spread (...):
const obj = { name:"hello", age:42, id:"3942" }; const objWithoutId = { ...o, id: undefined } const jsonWithoutId = JSON.stringify({...o, id:undefined});
fonte