From 1fef1f4353fc4ff9959a7c6c8044fa7be95bfe8e Mon Sep 17 00:00:00 2001 From: nianqin Date: Mon, 26 Aug 2019 16:21:54 +0800 Subject: [PATCH 1/4] support serialize undefined --- README.md | 2 +- index.js | 22 +++++++++++++++++++--- 2 files changed, 20 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..e1a218d 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. @@ -134,7 +146,7 @@ module.exports = function serialize(obj, options) { if (typeof str !== 'string') { return String(str); } - + // Replace unsafe HTML and invalid JavaScript line terminator chars with // their safe Unicode char counterpart. This _must_ happen before the // regexps and functions are serialized and added back to the string. @@ -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); From a7395cb36a75242800383e8f9b3f74492bcd0137 Mon Sep 17 00:00:00 2001 From: nianqin Date: Mon, 26 Aug 2019 16:40:25 +0800 Subject: [PATCH 2/4] support serialize undefined --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index e1a218d..ea0e6fb 100644 --- a/index.js +++ b/index.js @@ -154,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; } From 45604d48e78101bd171c28fc1ce5b01c27318243 Mon Sep 17 00:00:00 2001 From: nianqin Date: Wed, 28 Aug 2019 20:23:37 +0800 Subject: [PATCH 3/4] add serialize undefined test --- test/unit/serialize.js | 7 +++++++ 1 file changed, 7 insertions(+) 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 () { From d6d281f73f53f09c8835c9bf3224bd4aba82250d Mon Sep 17 00:00:00 2001 From: nianqin Date: Thu, 29 Aug 2019 09:56:52 +0800 Subject: [PATCH 4/4] remove unnecessary indent --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index ea0e6fb..41a8999 100644 --- a/index.js +++ b/index.js @@ -146,7 +146,7 @@ module.exports = function serialize(obj, options) { if (typeof str !== 'string') { return String(str); } - + // Replace unsafe HTML and invalid JavaScript line terminator chars with // their safe Unicode char counterpart. This _must_ happen before the // regexps and functions are serialized and added back to the string.