I have tried implement a replacer function for JSON.stringify() that detect if a value is buffer or not, but, when JSON.stringify call back my replacer, it is not a buffer anymore. Why?
Of course i can just iterate my object and replace buffers for string, but why this replacer doesn’t work?
const anObject = {
aBuffer: Buffer.from("This is a Buffer")
}
console.log("Serialized:", JSON.stringify(anObject, (key,value) => Buffer.isBuffer(value) ? value.toString("hex") : value));
console.log("Expected:", `{aBuffer: ${anObject.aBuffer.toString("hex")}}`)
console.log("Buffer is buffer:", Buffer.isBuffer(anObject.aBuffer)); //same result using instanceof Buffer
Results:
Serialized: {"aBuffer":{"type":"Buffer","data":[84,104,105,115,32,105,115,32,97,32,66,117,102,102,101,114]}}
teste.js:5
Expected: {aBuffer: 54686973206973206120427566666572}
teste.js:6
Buffer is buffer: true
The Buffer prototype has a .toJSON()
function defined, which returns an object with “type” and “data” properties. The runtime checks for .toJSON()
before it checks for a replacer function to call. Thus, your buffer turns into that object representation, and then your replacer doesn’t recognize it.
You could override the default .toJSON()
but that seems a little crazy. It would be less crazy to do it on instances of objects as necessary.
You can check this old bug report.