It doesn't do the same thing. JSON.stringify(token) is calling Roll20's serialization code (function toJSON() ), which exposes the properties in the format we are expecting. Object.assign() gives us the raw internal properties (this is for a character because I'm lazy that way...): { "attributes": { "name": "foo4", "bio": "", "gmnotes": "", "_defaulttoken": "", "archived": false, "inplayerjournals": "all", "controlledby": "-JS3qKxIUPHLzSbK24ve", "_id": "-LKRh66mxHoDFopfOQZi", "_type": "character", "avatar": "" }, "updatequeue": {}, "id": "-LKRh66mxHoDFopfOQZi", "fbpath": "/characters/-LKRh66mxHoDFopfOQZi", "_changing": false, "changed": {}, "_pending": false } Looking at that indicates that using something like: Object.assign({},token.attributes) Will (probably) give us what we expect: { "name": "foo5", "bio": "", "gmnotes": "", "_defaulttoken": "", "archived": false, "inplayerjournals": "all", "controlledby": "-JS3qKxIUPHLzSbK24ve", "_id": "-LKRi8t4mQv0ea_HLSJZ", "_type": "character", "avatar": "" } However, I'm not sure I like that very much as it relies on the implementation rather than the interface. toJSON() may be a bit slower, but it at least feels a bit safer. Honestly, I've not noticed any lag using JSON.parse(JSON.stringify(token)). Those are probably implemented in native code and running quite quickly, I'd have to do some benchmarks to see if they're even an issue in the API.