To simplify understanding, I'll create an example closer to reality:
const obj = {
"name": "John Doe",
"age": 34,
"parents": [
{
"name": "Derp",
"age": 63,
"gender": "male"
}, {
"name": "Derpina",
"age": 62,
"gender": "female"
}
]
};
Assuming the intention is to serialize the object obj
by ignoring the age
attribute. A detail is that not only the object itself has the age
attribute, but also child objects have (in this case, the two objects in parents
). If the intention in this case is to remove all age
attributes, no matter where it is, there are two solutions (others have been addressed in the other responses):
First solution: pass as second parameter of JSON.stringify
a list of the attributes that you want to keep when serializing the object. However, this list of attributes should not only address the attributes of the original object, but all the attributes of all related objects that it is desired to maintain. For example, the internal objects parents
have the gender
attribute that the main object does not have and even then that attribute must be listed:
const obj = {
"name": "John Doe",
"age": 34,
"parents": [
{
"name": "Derp",
"age": 63,
"gender": "male"
}, {
"name": "Derpina",
"age": 62,
"gender": "female"
}
]
};
console.log(JSON.stringify(obj, ["name", "parents", "gender"]));
If gender
is not listed, the attribute will be removed from internal objects when serializing.
Second solution: also using the second parameter of JSON.stringify
, but now defining a function that will execute the logic of maintaining or not a value in the object. The function receives two parameters: the key, the name of the attribute, and their respective value. The logic here would be quite simple: if the key matches the attribute we want to remove, we return the value undefined
, otherwise it returns the value itself.
const obj = {
"name": "John Doe",
"age": 34,
"parents": [
{
"name": "Derp",
"age": 63,
"gender": "male"
}, {
"name": "Derpina",
"age": 62,
"gender": "female"
}
]
};
console.log(JSON.stringify(obj, function (key, value) {
if (key == "age") {
return undefined;
}
return value;
}));
This form is relatively more versatile than the first, because instead of specifying which attributes you want to keep, you specify which attributes you want to remove, regardless of the structure of the rest of the object.
Not modifying internal objects
Both solutions remove the attribute from the most internal objects, so if you want to keep them by removing the attribute from the main object, other solutions are needed.
toJSON function: as shown in the L.Albano response , it is possible define a toJSON
function on the object that will be called when serializing it. The result of serialization will actually be the serialization of the return of this function. L. Albano showed how to do the object clone manually, but it is possible to do it dynamically and then remove the desired attribute.
const obj = {
"name": "John Doe",
"age": 34,
"parents": [
{
"name": "Derp",
"age": 63,
"gender": "male"
}, {
"name": "Derpina",
"age": 62,
"gender": "female"
}
],
toJSON: function () {
// Clona o objeto:
const clone = Object.assign({}, this);
// Remove o atributo desejado:
delete clone["age"];
// Retorna o clone modificado:
return clone;
}
};
console.log(JSON.stringify(obj));
In this way, only the age
attribute of the main object is removed, while the internal objects are retained.
Cloning the object using Object.assign
is only possible from ECMAScript 5 (ES6), but if desired, there are polyfills . Another technique of cloning objects is to combine JSON.parse
with JSON.stringify
, however this technique is not applicable in this example since it would generate an infinite recursion.