Encoding symbol keys in JSON?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Encoding symbol keys in JSON?

Alex Vincent
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
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Encoding symbol keys in JSON?

Isiah Meadows-2

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 <[hidden email]> 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
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Encoding symbol keys in JSON?

Allen Wirfs-Brock
In reply to this post by Alex Vincent
This sounds like a use case for Symbol.for https://tc39.github.io/ecma262/#sec-symbol.for 
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss