Maybe resurrecting an object should remove the "#" property
atduskgreg opened this issue · 3 comments
Roundtripping objects through resurrect adds a "#" key to them:
function TestObject(){
this.cats = [];
this.dogs = [];
}
t = new TestObject();
Object.keys(t);
// => ["cats", "dogs"]
r = new Resurrect();
Object.keys(r.resurrect(r.stringify(t)));
// => ["#", "cats", "dogs"]
I had a function that iterated through object keys in order to do some processing I wanted to do on all of the object's properties. It works with never-resurrected objects but not with those stringified and then resurrect because of this introduced "#" key. So I had to add an extra check to my code that specifically looks for the "#" key and handles it in a special case.
Maybe resurrect should strip out those "#" properties when resurrecting objects? There's probably an argument to be made that I shouldn't be writing code that does stuff like that iteration through properties, but I'm not sure resurrect should enforce that idea.
Or maybe I'm fundamentally misunderstanding how this library works and somehow the objects permanently use that property to look up their functions instead of actually having their original type after being resurrected?
If that extra property is causing problems, just configure Resurrect for
cleanup.
new Resurrect({cleanup: true})
This will remove Resurrect's extra properties using the delete keyword.
The reason this might not be desirable (and why it's left off by
default) is because it wreaks havoc on the JavaScript engine's optimizer
(hidden classes, etc.). Using delete communicates "this is a hash table,
not a struct." If you're iterating over properties then you're probably
using it like a hash table anyway -- or you're writing another
reflective library like ResurrectJS.
Someday when ES6 is practical without compiling to ES5 (still some years
away), I'll rewrite ResurrectJS to take advantage of it so that this
issue becomes irrelevant: private symbol properties, sets, hash tables,
etc.
@skeeto That totally makes sense. Thanks for explaining it. In my case most of my objects are actually structs with behavior, this just happened to be a case where some data doesn't have any behavior associated with it so ended up as basically a hash. But I think overall I'm much better off without cleanup.
Anyway, thanks for this great library. I'm using it in a game I'm making about being a Showrunner on a TV show. I wrote up a (kind of long) post about implementing game saving with resurrect.js (and trying to design against save scumming) here on my dev blog: http://showrunnergame.tumblr.com/post/135697213479/implementing-game-saving-and-discouraging-save