I have read about the replacer function and am unable to understand how it operates. I read
it here. The article explains the replacer but what it doesn't explain is from where the final output gets its keys from? If you see the function, we are only returning the value. The output should only contain the "values" but it contains keys too. If we aren't returning the keys then how the keys are in the output? I understand that for the first call the replacer function receives an empty key and the complete object as its value, therefore it prints in the first call:
key
let meetup = {
title: "Conference",
occupiedBy: [{name: "John"}, {name: "Alice"}],
place: room
};
And in the second call, the key "title" is used as the replacer's key parameter, and the value "Conference" is used as its value parameter. The if statement checks whether the key is not empty and if the value equals "meetup" and if the statement is true it returns "undefined", otherwise it returns only value. Here I am getting confused. Why we are only returning the value? If we are only returning the "conference" value then how is the key "title" getting returned if we didn't return it?
let room = {
number: 23
};
let meetup = {
title: "Conference",
occupiedBy: [{name: "John"}, {name: "Alice"}],
place: room
};
// circular references
room.occupiedBy = meetup;
meetup.self = meetup;
console.log( JSON.stringify(meetup, function replacer(key,value){
console.log('keys', key);
console.log('value', value);
if ( key != "" && value == meetup){
return undefined;
}
else {
return value;
}
},3));
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
The replacer function's only purpose is to (possibly) change the value returned. The key used at that position in the stringified object is known and constant in JSON.stringify
's internals. Just because it also takes a parameter of the key does not mean that what is returned is used as the key.
For a trivial example of transforming an object with a function that takes a key and a value, but only changes the value, see here:
const transformObj = (obj, replacer) => {
const newObj = {};
for (const [key, value] of Object.entries(obj)) {
const transformedValue = replacer(key, value);
newObj[key] = transformedValue;
}
return newObj;
};
console.log(transformObj(
{ foo: '5', bar: '10' },
(key, value) => Number(value)
));
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
The key can be passed to the replacer without requiring the replacer to also return a new key somehow.