W3C home > Mailing lists > Public > public-script-coord@w3.org > October to December 2016

Re: JSON-serializable object

From: Boris Zbarsky <bzbarsky@mit.edu>
Date: Wed, 16 Nov 2016 10:04:32 -0500
To: public-script-coord@w3.org
Message-ID: <ceb16f2e-5e0c-a85e-1689-6460d4b886fb@mit.edu>
On 11/16/16 1:17 AM, Marcos Caceres wrote:
> However, it doesn't define how a UA actually would check the above...
> apart from basically calling:
>
> ```JS
> try {
>    JSON.parse(JSON.stringify(obj));
> } catch(err){
>    throw new Error("Not a JSON-serializable object");
> }

Not good enough.  You can easily create a proxy which will throw on 
every even-numbered call to JSON.stringify, say.

A UA _could_ check something along the lines of (for non-array objects):

1) The [[GetPrototypeOf]] of the object is 
https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-getprototypeof

2) The prototype of the object is Object.prototype.

3) The object's [[GetOwnProperty]] is 
https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-getownproperty-p

4) The object's [[OwnPropertyKeys]] is 
https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys

4) Neither the object nor Object.prototype have an accessor property 
named "toJSON", and if they have a value propety with that name then its 
value is not callable.

5) The object is not a Number object or a String object or a Boolean object.

6) The object is not callable.

7) For each string-named own property of the object, the following hold:

   a) It is a value property.
   b) The value is an object, null, a boolean, a string, or a number.
   c) If the value is an object, it is itself JSON-serializable.
   d) If the value is a number, it's finite and is not -0.

Plus some conditions around arrays that I have not dug into.  At the 
very least requires no holes and that all values satisfy item 7 above.

I make no claim that the above checks are sufficient.  For example, I 
strongly suspect that if you take a Node with no extra properties 
defined on it and Object.setPrototypeOf its prototype to 
Object.prototype then it would pass all the above tests, but presumably 
not be considered "JSON-serializable" by the dataloss condition cited. 
But the above checks are certainly necessary.

Note also that whether an object is "JSON-serializable" by this 
definition depends on some seriously non-local state...

-Boris
Received on Wednesday, 16 November 2016 15:05:07 UTC

This archive was generated by hypermail 2.3.1 : Wednesday, 16 November 2016 15:05:07 UTC