JSON replacer is recursive. This then means it uses the same array for all objects it comes across. In other words, it uses the same values to map BAD.g's value. Since, Bad.g's value does not have any keys matching the ones you provided, nothing will get mapped properly. This means we have to add "2" to your array. Now "2" also has an object with different keys. We have already accounted for "b", so now we just need to add "w" to your array.

When providing an array to the replacer, best to think of the array as a list of all the keys you want mapped.

DEMO: http://jsfiddle.net/dirtyd77/whv7x6xc/4/

console.log(JSON.stringify(BAD, ['a', 'b', 'c', 'd', 'e', 'g', '2', 'w']));

Hope this helps and let me know if you have any questions.


Here is also a snippet from the documentation,

If you return any other object, the object is recursively stringified into the JSON string, calling the replacer function on each property, unless the object is a function, in which case nothing is added to the JSON string.


In the case for dynamic keys, you can always create a function to push to an array and use that array for your whitelist. Here is an example:

DEMO: http://jsfiddle.net/dirtyd77/whv7x6xc/5/

var BAD = {
    "a": "2",
    "b": 1,
    "c": "Nexus",
    "d": "Alligator",
    "e": 5,
    "f": 1431807036,
    "g": {
        "2": {
            "w": 17,
            "b": 5
        }
    }
}

var whitelist = [];

iterate(BAD);

console.log(whitelist, JSON.stringify(BAD, whitelist));

function iterate(obj){
    for(var key in obj){
        // may have to do some checking to ignore any keys you don't care about
        whitelist.push(key);
        // if value is an object, will use this same function to push to whitelist array
        if(typeof obj[key] === 'object'){
            return iterate(obj[key]);
        }
    }
}

You can also just use your existing whitelist and just append keys on your g key (given that isn't dynamic):

DEMO: http://jsfiddle.net/dirtyd77/whv7x6xc/6/

var whitelist = ['a', 'b', 'c', 'd', 'e', 'g'];

iterate(BAD.g);

console.log(whitelist, JSON.stringify(BAD, whitelist));

function iterate(obj){
    for(var key in obj){
        whitelist.push(key);
        if(typeof obj[key] === 'object'){
            return iterate(obj[key]);
        }
    }
}
Answer from Dom on Stack Overflow
Top answer
1 of 3
17

JSON replacer is recursive. This then means it uses the same array for all objects it comes across. In other words, it uses the same values to map BAD.g's value. Since, Bad.g's value does not have any keys matching the ones you provided, nothing will get mapped properly. This means we have to add "2" to your array. Now "2" also has an object with different keys. We have already accounted for "b", so now we just need to add "w" to your array.

When providing an array to the replacer, best to think of the array as a list of all the keys you want mapped.

DEMO: http://jsfiddle.net/dirtyd77/whv7x6xc/4/

console.log(JSON.stringify(BAD, ['a', 'b', 'c', 'd', 'e', 'g', '2', 'w']));

Hope this helps and let me know if you have any questions.


Here is also a snippet from the documentation,

If you return any other object, the object is recursively stringified into the JSON string, calling the replacer function on each property, unless the object is a function, in which case nothing is added to the JSON string.


In the case for dynamic keys, you can always create a function to push to an array and use that array for your whitelist. Here is an example:

DEMO: http://jsfiddle.net/dirtyd77/whv7x6xc/5/

var BAD = {
    "a": "2",
    "b": 1,
    "c": "Nexus",
    "d": "Alligator",
    "e": 5,
    "f": 1431807036,
    "g": {
        "2": {
            "w": 17,
            "b": 5
        }
    }
}

var whitelist = [];

iterate(BAD);

console.log(whitelist, JSON.stringify(BAD, whitelist));

function iterate(obj){
    for(var key in obj){
        // may have to do some checking to ignore any keys you don't care about
        whitelist.push(key);
        // if value is an object, will use this same function to push to whitelist array
        if(typeof obj[key] === 'object'){
            return iterate(obj[key]);
        }
    }
}

You can also just use your existing whitelist and just append keys on your g key (given that isn't dynamic):

DEMO: http://jsfiddle.net/dirtyd77/whv7x6xc/6/

var whitelist = ['a', 'b', 'c', 'd', 'e', 'g'];

iterate(BAD.g);

console.log(whitelist, JSON.stringify(BAD, whitelist));

function iterate(obj){
    for(var key in obj){
        whitelist.push(key);
        if(typeof obj[key] === 'object'){
            return iterate(obj[key]);
        }
    }
}
2 of 3
6

The replacer argument is deep, in that it affects the stringification of all properties, even if they're not on the first level. If you add "2" to the array, you'll see that the object is stringified, minus "w", because "w" is not allowlisted by replacer.

JSON.stringify(BAD, ['a', 'b', 'c', 'd', 'e', 'g', '2'])

Consider why you are using replacer. If you are using it to blocklist, instead of allowlist, you might be better served by passing in a function as opposed to an array.

JSON.stringify(BAD, function replacer(key, value) {
  var blocklist = ['b', 'g']
  return blocklist.indexOf(key) === -1 ? value : undefined
})
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Global_Objects › JSON › stringify
JSON.stringify() - JavaScript - MDN Web Docs
The JSON.stringify() static method converts a JavaScript value to a JSON string, optionally replacing values if a replacer function is specified or optionally including only the specified properties if a replacer array is specified.
Discussions

TIL — The power of JSON.stringify replacer parameter
Replacer?? I just met 'er! (i'm so sorry) More on reddit.com
🌐 r/javascript
42
378
October 12, 2019
JSON.stringify replacer option
Related: #1096. Not sure why the author closed the original issue as completed. Also not sure about your stance on discussions in closed issues so opening a new one What is the feature you are prop... More on github.com
🌐 github.com
3
May 27, 2024
JSON.stringify replacer
When you run JSON.stringify with a replacer function, the first thing it tries to replace is the entire JSON object, using the empty string as a key, before then going through the keys of the object. To illustrate, the code: let obj = { a: 5, b: 10, }; function replacer(key, value) { console.log(key, value); return value; } JSON.stringify(obj, replacer); would log '' {a:5,b:10} 'a' 5 'b' 10 And so, when you implicitly say to return undefined if the key isn’t a, that first replacement, of the entire object, returns undefined. More on reddit.com
🌐 r/learnjavascript
2
2
July 15, 2020
Stringying this JSON drops all elements of the nested array
There are a few misconceptions that are leading you astray. nested objects cant be stringified That is not true: JSON.stringify({ foo: { bar: 'baz' } }) //=> '{"foo":{"bar":"baz"}}' but if I just console.log the array by itself before returning, the array is correctly populated with the image data. That is because you are seeing a live representation of the object. By the time you observe it in the console, the array has been populated. Your issue is because of the asynchronicity as you had once thought. There are some solutions here . More on reddit.com
🌐 r/learnjavascript
5
5
October 25, 2023
🌐
pawelgrzybek
pawelgrzybek.com › til-the-power-of-json-stringify-replacer-parameter
TIL — The power of JSON.stringify replacer parameter | pawelgrzybek.com
November 11, 2019 - JSON.stringify() takes a second optional argument that can be a recursive replacer function or an array of white-listed keys to be stringified.
🌐
Dillion's Blog
dillionmegida.com › p › second-argument-in-json-stringify
The second argument in JSON.stringify() - Dillion's Blog
February 10, 2022 - const replacer = (key, value) => { if (key === "id") return `id-${value}` return value } console.log(JSON.stringify(object, replacer, 2)) // output // { // "name": "John", // "id": "id-john", // "obj": { // "name": "Jane", // "id": "id-jane" ...
🌐
Nocommandline
nocommandline.com › blog › json-stringify-replacer-parameter-buffer-and-uint8array
JSON.stringify(), Replacer Parameter, Buffer and Uint8Array
January 29, 2023 - The second parameter can be an array or a function called a replacer. When it's an array: If while converting your JSON object to a string, you want the final output to only have a subset of the JSON object keys, you pass the keys that you wish to keep, as an array to the JSON.stringify() command and only those keys will be returned from the JSON.stringify() call. See the code below for an example.
🌐
GitHub
gist.github.com › davidfurlong › 463a83a33b70a3b6618e97ec9679e490
JSON.stringify replacer function for having object keys sorted in output (supports deeply nested objects) · GitHub
function getUniqueObjects(arr) { const replacer = (key, value) => value && typeof value === "object" && !Array.isArray(value) ? Object.keys(value) .sort() .reduce((sorted, key) => { sorted[key] = value[key]; return sorted; }, {}) : value; return arr.filter( (v, i, a) => a.findIndex( (v2) => JSON.stringify(v2, replacer) === JSON.stringify(v, replacer) ) === i ); }
🌐
Reality Ripple
udn.realityripple.com › docs › Web › JavaScript › Reference › Global_Objects › JSON › stringify
JSON.stringify() - JavaScript - UDN Web Docs: MDN Backup
The JSON.stringify() method converts a JavaScript object or value to a JSON string, optionally replacing values if a replacer function is specified or optionally including only the specified properties if a replacer array is specified. The source for this interactive example is stored in a ...
Find elsewhere
🌐
Reddit
reddit.com › r/javascript › til — the power of json.stringify replacer parameter
r/javascript on Reddit: TIL — The power of JSON.stringify replacer parameter
October 12, 2019 - ... const myObject = { set: new Set([1, 2, 3, 4]) }; const replacer = (key, value) => { if (value instanceof Set) { return { __type: "Set", __value: Array.from(value) }; } return value; } const stringified = JSON.stringify(myObject, replacer); ...
🌐
GitHub
gist.github.com › bennadel › 2396556b61cf7caa2b5a558d15ed0ec3
Using JSON.stringify() Replacer Function To Recursively Serialize And Sanitize Log Data · GitHub
Using JSON.stringify() Replacer Function To Recursively Serialize And Sanitize Log Data · Raw · error.js · This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
🌐
Execute Program
executeprogram.com › courses › modern-javascript › lessons › customizing-json-serialization
Modern JavaScript: Customizing JSON Serialization
Learn programming languages like TypeScript, Python, JavaScript, SQL, and regular expressions. Interactive with real code examples.
🌐
RestfulAPI
restfulapi.net › home › json › json stringify()
JSON stringify() - REST API Tutorial
November 3, 2023 - The JSON.stringify() function, as name suggests, converts a JavaScript value to a serialized JSON string. JSON.stringify() can optionally use a replacer function to replace values using custom logic. 1. Syntax The syntax of the JSON.stringify() method is: 1.1. Method Parameters 2. JSON.stringify() Example Program output.
🌐
Medium
smali-kazmi.medium.com › how-to-use-json-stringify-b3a3ca7fbd21
How to use replacer with JSON.stringify() | by Mudaser Ali | Medium
October 27, 2019 - Function Example · Suppose your JSON object contains a Set property · var foo = { foundation: 'medium', purpose: 'share stories', owner: 'SM@K', hobbies: new Set(['coding', 'photography', 'eating', 'play games']) };JSON.stringify(foo);// "{"foundation":"medium","purpose":"share stories","owner":"SM@K","hobbies":{}}"//hobbies = {} ?? so we can resolve this issue by using replacer argument ·
🌐
W3Schools
w3schools.com › jsref › jsref_stringify.asp
JavaScript JSON stringify() Method
... /*replace the value of "city" to upper case:*/ var obj = { "name":"John", "age":"39", "city":"New York"}; var text = JSON.stringify(obj, function (key, value) { if (key == "city") { return value.toUpperCase(); } else { return value; } }); ...
🌐
Esdiscuss
esdiscuss.org › topic › string-prototype-replace-problems-with-json-stringify-and-serialization-of-objects
String.prototype.replace() problems with JSON.stringify() and serialization of Objects
Example: var func = function() ... Inside an engine, this would be a JSON.stringify(environment); or similar var x = 'This is a simple {{blob}}'; var y = x.replace('{{blob}}', data, true); // note the suggested optional flag An example implementation I made for showing the ...
🌐
Bennadel
bennadel.com › blog › 3278-using-json-stringify-replacer-function-to-recursively-serialize-and-sanitize-log-data.htm
Using JSON.stringify() Replacer Function To Recursively Serialize And Sanitize Log Data
April 21, 2020 - That said, I think we can use the JSON.stringify() replacer function to simplify our lives. With the replacer function, we gain granular control over how data is moved into (or excluded from) the JSON (JavaScript Object Notation) result.
🌐
Codeproject
reference.codeproject.com › javascript
javascript JSON.stringify() - CodeProject Reference
November 5, 2021 - In a case where you want to store an object created by your user and allowing it to be restored even after the browser has been closed, the following example is a model for the applicability of JSON.stringify(): Functions are not a valid JSON data type so they will not work. However, they can be displayed if first converted to a string (e.g. in the replacer), via the function's toString method.
🌐
GitHub
github.com › honojs › hono › issues › 3360
JSON.stringify replacer option · Issue #3360 · honojs/hono
May 27, 2024 - I'm thinking as an initialization option when initializing the Hono app, we can pass a custom stringifier · const app = new Hono({ jsonStringify: jsonStringify }) ... A possible footgun migth be that the replacer function could change the types, ...
Author   juliusmarminge
🌐
Medium
medium.com › @mujaffarhssn › are-you-familiar-with-the-hidden-powers-of-json-stringify-function-59e230accd99
Are You Familiar with the Hidden Powers of JSON.stringify() Function? | by TechInsights | Medium
November 4, 2023 - At its core, JSON.stringify() converts a JavaScript object into a JSON string. Here's the basic syntax: ... space: An optional parameter that specifies the indentation of nested structures in the resulting string. The replacer function is a powerful tool that allows us to customize the ...
🌐
Joe Attardi
joeattardi.dev › customizing-jsonparse-and-jsonstringify
Customizing `JSON.parse` and `JSON.stringify` - Joe Attardi
February 15, 2025 - However, the original object can ... // original property return this.lastLogin.getTime(); } return value; } const json = JSON.stringify(user, replacer);...