diff --git a/index.js b/index.js index 156f8f9..c873e4d 100644 --- a/index.js +++ b/index.js @@ -11,7 +11,7 @@ var randomBytes = require('randombytes'); // Generate an internal UID to make the regexp pattern harder to guess. var UID_LENGTH = 16; var UID = generateUID(); -var PLACE_HOLDER_REGEXP = new RegExp('(\\\\)?"@__(F|R|D|M|S|A|U|I|B|L)-' + UID + '-(\\d+)__@"', 'g'); +var PLACE_HOLDER_REGEXP = new RegExp('(\\\\)?"@__(F|R|D|M|S|A|U|I|B|L|N)-' + UID + '-(\\d+)__@"', 'g'); var IS_NATIVE_CODE_REGEXP = /\{\s*\[native code\]\s*\}/g; var IS_PURE_FUNCTION = /function.*?\(/; @@ -73,6 +73,7 @@ module.exports = function serialize(obj, options) { var infinities= []; var bigInts = []; var urls = []; + var nans = []; // Returns placeholders for functions and regexps (identified by index) // which are later replaced by their string representation. @@ -83,6 +84,10 @@ module.exports = function serialize(obj, options) { deleteFunctions(value); } + if (typeof value === 'number' && isNaN(value)) { + return '@__N-' + UID + '-' + (nans.push(value) - 1) + '__@'; + } + if (!value && value !== undefined && value !== BigInt(0)) { return value; } @@ -133,6 +138,7 @@ module.exports = function serialize(obj, options) { return '@__I-' + UID + '-' + (infinities.push(origValue) - 1) + '__@'; } + if (type === 'bigint') { return '@__B-' + UID + '-' + (bigInts.push(origValue) - 1) + '__@'; } @@ -210,7 +216,7 @@ module.exports = function serialize(obj, options) { str = str.replace(UNSAFE_CHARS_REGEXP, escapeUnsafeChars); } - if (functions.length === 0 && regexps.length === 0 && dates.length === 0 && maps.length === 0 && sets.length === 0 && arrays.length === 0 && undefs.length === 0 && infinities.length === 0 && bigInts.length === 0 && urls.length === 0) { + if (functions.length === 0 && regexps.length === 0 && dates.length === 0 && maps.length === 0 && sets.length === 0 && arrays.length === 0 && undefs.length === 0 && infinities.length === 0 && bigInts.length === 0 && urls.length === 0 && nans.length === 0) { return str; } @@ -261,6 +267,10 @@ module.exports = function serialize(obj, options) { return "new URL(" + serialize(urls[valueIndex].toString(), options) + ")"; } + if (type === 'N') { + return 'NaN'; + } + var fn = functions[valueIndex]; return serializeFunc(fn); diff --git a/test/unit/serialize.js b/test/unit/serialize.js index 54167d0..f4a8ffd 100644 --- a/test/unit/serialize.js +++ b/test/unit/serialize.js @@ -554,6 +554,19 @@ describe('serialize( obj )', function () { }); }); + describe('NaN', function () { + it('should serialize NaN', function () { + expect(serialize(NaN)).to.equal('NaN'); + expect(serialize({t: [NaN]})).to.be.a('string').equal('{"t":[NaN]}'); + }); + + it('should deserialize NaN', function () { + var d = eval(serialize(NaN)); + expect(d).to.be.a('Number'); + expect(isNaN(d)).to.equal(true); + }); + }); + describe('backwards-compatability', function () { it('should accept `space` as the second argument', function () { expect(serialize([1], 0)).to.equal('[1]');