`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?
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss