Implementing an identical JSON.stringify
Michael Theriot
michael.lee.theriot at gmail.com
Sat Aug 4 22:16:10 UTC 2018
`JSON.stringify` has unintuitive behavior regarding interal slots.
```js
// Number with [[NumberData]]
// "0"
JSON.stringify(Object(Number(0)));
// Number without [[NumberData]]
// "{}"
JSON.stringify(Reflect.construct(Object, [], Number));
// Number without [[NumberData]]
// Number with [[StringData]]
// throws TypeError
JSON.stringify(Reflect.construct(String, [], Number));
// String with [[StringData]]
// ""
JSON.stringify(Object(String()));
// String without [[StringData]]
// "{}"
JSON.stringify(Reflect.construct(Object, [], String));
// String without [[StringData]]
// String with [[NumberData]]
// throws TypeError
JSON.stringify(Reflect.construct(Number, [], String));
// Object with [[StringData]]
// "[object String]"
JSON.stringify(Reflect.construct(String, [], Object));
// Object with [[NumberData]]
// null
JSON.stringify(Reflect.construct(Number, [], Object));
```
Weird, but not impossible to implement.
* You can detect class with instanceof
* You can detect internal slots by try-catching `<class>.prototype.valueOf`
e.g.
```js
const isNumberInstance = (item) => item instanceof Number;
const isStringInstance = (item) => item instanceof String;
const hasNumberData = (item) => {
try { Number.prototype.valueOf.call(item); } catch { return false; }
return true;
};
const hasStringData = (item) => {
try { String.prototype.valueOf.call(item); } catch { return false; }
return true;
};
```
Since this relies on having a reference to the classes, it will not work
with an instance of `Number` from another realm for example.
```js
const item = Reflect.construct(iframe.contentWindow.String, [],
iframe.contentWindow.Number);
iframe.contentWindow.Number !== Number;
```
I think this is related to `Array.isArray`. Is there an equivalent
`Number.isNumber`? Or is this just something only `JSON.stringify` can do?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20180804/e2ac7da6/attachment.html>
More information about the es-discuss
mailing list