Preserve property attributes (writable, custom) after JSON.parse ()
Lets say that I am creating an object elsewhere and passing it somehow to my module. Maybe it was created on the server in node.js
, maybe it was created in another module and for some reason I JSON.stringify()
started it and passed the serialized version (especially if it came from the server). But I want this particular property to be immutable:
var foo = {};
Object.defineProperty(foo, 'bar', {
value: 'bar',
writeable: false,
enumerable: true
});
console.log(foo.bar); //bar
foo.bar = 'foo'; //fails, throws err in strict
console.log(foo.bar); //still bar
var fii = JSON.parse(JSON.stringify(foo));
console.log(fii.bar); //still bar
fii.bar = 'foo'; //succeeds
console.log(fii.bar); //now foo
Is there a way to preserve this metadata so that the property is bar
immutable without sending it separately?
source to share
You can string together property descriptors as in
// set up object to be serialized--from OP question
var foo = {};
Object.defineProperty(foo, 'bar', {
value: 'bar',
writable: false,
enumerable: true
});
// create an object of property descriptors
var descriptors = {};
Object.keys(foo).forEach(function(key) {
descriptors[key] = Object.getOwnPropertyDescriptor(foo, key);
});
var json = JSON.stringify(descriptors);
// "{"bar":{"value":"bar","writable":false,"enumerable":true,"configurable":false}}"
Now, to restore:
descriptors = JSON.parse(json); foo = {}; Object.defineProperties(foo, descriptors);
Of course, this will not work with accessor type descriptors that contain get
and / or set
nested objects, etc. etc.
Using flags on keys
Another idea is to encode the writeability into the key name through path and path conversions:
// Mark unwritable properties by changing keyname to 'prop:unwritable'.
function markImmutable(obj) {
for (var p in obj) {
if (!Object.getOwnPropertyDescriptor(obj, p).writable) {
obj[p + ':unwritable'] = obj[p];
delete obj[p];
}
}
}
markImmutable(foo)
> Object {bar:unwritable: "bar"}
Then tweak that, and after parsing, do the reverse transformation.