From 356987fa6f72f747b3abd0e6f7318a800a5fb7ff Mon Sep 17 00:00:00 2001 From: nqdy666 Date: Thu, 29 Aug 2019 20:34:16 +0800 Subject: [PATCH] support serialize undefined (#54) --- README.md | 2 +- index.js | 22 +++++++++++++++++++--- test/unit/serialize.js | 7 +++++++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 585cd54..c0edf01 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ serialize({ The above will produce the following string output: ```js -'{"str":"string","num":0,"obj":{"foo":"foo"},"arr":[1,2,3],"bool":true,"nil":null,date:new Date("2016-04-28T22:02:17.156Z"),new Map([["hello", "world"]]),new Set([123,456]),"fn":function echo(arg) { return arg; },"re":/([^\\s]+)/g}' +'{"str":"string","num":0,"obj":{"foo":"foo"},"arr":[1,2,3],"bool":true,"nil":null,"undef":undefined,"date":new Date("2016-04-28T22:02:17.000Z"),"map":new Map([["hello","world"]]),"set":new Set([123,456]),"fn":function echo(arg) { return arg; },"re":/([^\s]+)/g}' ``` Note: to produced a beautified string, you can pass an optional second argument to `serialize()` to define the number of spaces to be used for the indentation. diff --git a/index.js b/index.js index b10a500..41a8999 100644 --- a/index.js +++ b/index.js @@ -8,7 +8,7 @@ See the accompanying LICENSE file for terms. // Generate an internal UID to make the regexp pattern harder to guess. var UID = Math.floor(Math.random() * 0x10000000000).toString(16); -var PLACE_HOLDER_REGEXP = new RegExp('"@__(F|R|D|M|S)-' + UID + '-(\\d+)__@"', 'g'); +var PLACE_HOLDER_REGEXP = new RegExp('"@__(F|R|D|M|S|U)-' + UID + '-(\\d+)__@"', 'g'); var IS_NATIVE_CODE_REGEXP = /\{\s*\[native code\]\s*\}/g; var IS_PURE_FUNCTION = /function.*?\(/; @@ -44,11 +44,13 @@ module.exports = function serialize(obj, options) { var dates = []; var maps = []; var sets = []; + var undefs = []; // Returns placeholders for functions and regexps (identified by index) // which are later replaced by their string representation. function replacer(key, value) { - if (!value) { + + if (!value && value !== undefined) { return value; } @@ -79,6 +81,10 @@ module.exports = function serialize(obj, options) { return '@__F-' + UID + '-' + (functions.push(origValue) - 1) + '__@'; } + if (type === 'undefined') { + return '@__U-' + UID + '-' + (undefs.push(origValue) - 1) + '__@'; + } + return value; } @@ -119,6 +125,12 @@ module.exports = function serialize(obj, options) { return serializedFn; } + // Protects against `JSON.stringify()` returning `undefined`, by serializing + // to the literal string: "undefined". + if (obj === undefined) { + return String(obj); + } + var str; // Creates a JSON string representation of the value. @@ -142,7 +154,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) { + if (functions.length === 0 && regexps.length === 0 && dates.length === 0 && maps.length === 0 && sets.length === 0 && undefs.length === 0) { return str; } @@ -166,6 +178,10 @@ module.exports = function serialize(obj, options) { return "new Set(" + serialize(Array.from(sets[valueIndex].values()), options) + ")"; } + if (type === 'U') { + return 'undefined' + } + var fn = functions[valueIndex]; return serializeFunc(fn); diff --git a/test/unit/serialize.js b/test/unit/serialize.js index a350449..e66977c 100644 --- a/test/unit/serialize.js +++ b/test/unit/serialize.js @@ -57,6 +57,13 @@ describe('serialize( obj )', function () { var ws = String.fromCharCode(8232); expect(eval(serialize(ws))).to.equal(ws); }); + + it('should serialize undefined correctly', function () { + var obj; + var str = '{"undef":undefined,"nest":{"undef":undefined}}'; + eval('obj = ' + str); + expect(serialize(obj)).to.equal(str); + }); }); describe('functions', function () {