Encoding symbol keys in JSON?
# Isiah Meadows (7 years ago)
I honestly wouldn't worry about this edge case - it's rare you actually would want to serialize symbols, and it's usually best handled at the application level, not the framework level.
I honestly wouldn't worry about this edge case - it's rare you actually would want to serialize symbols, and it's usually best handled at the application level, not the framework level. On Mon, Nov 13, 2017, 06:10 Alex Vincent <ajvincent at gmail.com> wrote: > In modern ECMAScript, objects can have symbols for property names instead > of strings. This leads me to a problem in my es7-membrane project: how do > I translate those symbol keys into JSON for a reusable file? (I partially > answer my own question below.) > > Consider the following code: > > const X = {}; > const two = Symbol("two"); > Reflect.defineProperty(X, "one", {value: 1, writable: true, enumerable: > true, configurable: true}); > Reflect.defineProperty(X, two, {value: 2, writable: true, enumerable: > true, configurable: true}); > return JSON.stringify(Reflect.ownKeys(X)); > > In both Mozilla Firefox and Google Chrome, this returns ["one", null]. I > suppose this is part of the ECMAScript's latest standard. I do see > JSON.stringify has a "replacer" callback argument, and JSON.parse has a > "reviver" argument. I presume that these are here to solve > encoding/decoding problems with JSON. This may be the route I take... > > At first, serializing shouldn't be a problem: if I hit a symbol as a key, > I could use the replacer functionality to deliver a standard > JSON-serializable object. > > But what if the ordering of keys is not guaranteed? I'm referring > specifically to the case of a developer modifying X's properties in the > above snippet - say, by defining Symbol("three") as a key before the two > key. Or worse, by defining a different Symbol("two") before the existing > two key? I am not referring to the case of the developer modifying the > results from Result.ownKeys(). > > Now, all of a sudden, this little stringify problem has possibly morphed > into a diff/merge problem: between yesterday's serialized JSON for ownKeys > and today's, someone has cleverly inserted a symbol where there was another > in the list of keys. My code is supposed to infer today from yesterday's > generated JSON which property key belongs to which property value. With > symbols - especially identically-keyed symbols - I could lose that > consistency if I'm not careful. > > (Side note: for es7-membrane, I faced a similar but easily solvable > problem, where Reflect.ownKeys(function() {}) returned different results in > different browsers - especially when the function passed into ownKeys had > additional properties. In that case all the properties were strings, so I > just extracted the common set of string-named properties and put them at > the front of the keys list for consistency.) > > I'm looking for advice - including the very real possibility that I'm > overthinking this or worrying too much about an edge case. > > -- > "The first step in confirming there is a bug in someone else's work is > confirming there are no bugs in your own." > -- Alexander J. Vincent, June 30, 2001 > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20171113/d6656f9d/attachment-0001.html>
# Allen Wirfs-Brock (7 years ago)
This sounds like a use case for Symbol.for tc39.github.io/ecma262/#sec-symbol.for, tc39.github.io/ecma262/#sec-symbol.for
This sounds like a use case for Symbol.for https://tc39.github.io/ecma262/#sec-symbol.for <https://tc39.github.io/ecma262/#sec-symbol.for> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20171113/7a45df2e/attachment.html>
In modern ECMAScript, objects can have symbols for property names instead of strings. This leads me to a problem in my es7-membrane project: how do I translate those symbol keys into JSON for a reusable file? (I partially answer my own question below.)
Consider the following code:
const X = {}; const two = Symbol("two"); Reflect.defineProperty(X, "one", {value: 1, writable: true, enumerable: true, configurable: true}); Reflect.defineProperty(X, two, {value: 2, writable: true, enumerable: true, configurable: true}); return JSON.stringify(Reflect.ownKeys(X));
In both Mozilla Firefox and Google Chrome, this returns ["one", null]. I suppose this is part of the ECMAScript's latest standard. I do see JSON.stringify has a "replacer" callback argument, and JSON.parse has a "reviver" argument. I presume that these are here to solve encoding/decoding problems with JSON. This may be the route I take...
At first, serializing shouldn't be a problem: if I hit a symbol as a key, I could use the replacer functionality to deliver a standard JSON-serializable object.
But what if the ordering of keys is not guaranteed? I'm referring specifically to the case of a developer modifying X's properties in the above snippet - say, by defining Symbol("three") as a key before the two key. Or worse, by defining a different Symbol("two") before the existing two key? I am not referring to the case of the developer modifying the results from Result.ownKeys().
Now, all of a sudden, this little stringify problem has possibly morphed into a diff/merge problem: between yesterday's serialized JSON for ownKeys and today's, someone has cleverly inserted a symbol where there was another in the list of keys. My code is supposed to infer today from yesterday's generated JSON which property key belongs to which property value. With symbols - especially identically-keyed symbols - I could lose that consistency if I'm not careful.
(Side note: for es7-membrane, I faced a similar but easily solvable problem, where Reflect.ownKeys(function() {}) returned different results in different browsers - especially when the function passed into ownKeys had additional properties. In that case all the properties were strings, so I just extracted the common set of string-named properties and put them at the front of the keys list for consistency.)
I'm looking for advice - including the very real possibility that I'm overthinking this or worrying too much about an edge case.