From 9343a42d864ccc723303c01ee604028b15dd6d42 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Sat, 18 Mar 2017 12:37:40 -0400 Subject: [PATCH] Intern object keys as well as values. --- custom.js | 33 ++++++++++++++++++++++++++++ index.js | 64 +++++++++++++++++++++++++------------------------------ 2 files changed, 62 insertions(+), 35 deletions(-) diff --git a/custom.js b/custom.js index dd80993..9597d76 100644 --- a/custom.js +++ b/custom.js @@ -6,6 +6,39 @@ var mapTag = "[object Map]"; var arson = require("./index.js"); +function isPlainObject(value) { + var isObject = value && typeof value === "object"; + if (isObject) { + var proto = Object.getPrototypeOf + ? Object.getPrototypeOf(value) + : value.__proto__; + return proto === Object.prototype; + } + return false; +} + +arson.registerType("o", { + deconstruct: function (obj, tolerant) { + if (tolerant || isPlainObject(obj)) { + var props = []; + Object.keys(obj).forEach(function (key) { + props.push(key, obj[key]); + }); + return props; + } + }, + + reconstruct: function (props) { + if (props) { + for (var i = 0; i < props.length; i += 2) { + this[props[i]] = props[i + 1]; + } + } else { + return {}; + } + } +}); + typeof Buffer === "function" && typeof Buffer.isBuffer === "function" && arson.registerType("Buffer", { diff --git a/index.js b/index.js index 8428a34..456e192 100644 --- a/index.js +++ b/index.js @@ -52,41 +52,46 @@ function toTable(value) { var values = []; var getIndex = makeGetIndexFunction(values); + function asType(value, typeName, tolerant) { + // If value is not a plain Object, but something exotic like a + // Date or a RegExp, serialize it as an array with typeName as + // its first element. These arrays can be distinguished from + // normal arrays, because all other non-empty arrays will be + // serialized with a numeric value as their first element. + var args = customTypes[typeName].deconstruct(value, tolerant); + if (args) { + args.forEach(function (arg, i) { + args[i] = getIndex(arg); + }); + args.unshift(typeName); + return args; + } + } + function copy(value) { var result = value; if (value && typeof value === "object") { - var keys = Object.keys(value); - - if (isPlainObject(value)) { - result = {}; - - } else if (Array.isArray(value)) { + if (Array.isArray(value)) { result = getArrayOfHoles(value.length); - } else { - for (var typeName in customTypes) { - // If value is not a plain Object, but something exotic like a - // Date or a RegExp, serialize it as an array with typeName as - // its first element. These arrays can be distinguished from - // normal arrays, because all other non-empty arrays will be - // serialized with a numeric value as their first element. - var args = customTypes[typeName].deconstruct(value); - if (args) { - for (var i = 0; i < args.length; ++i) { - args[i] = getIndex(args[i]); - } - args.unshift(typeName); - return args; + for (var i = 0; i < value.length; ++i) { + if (value.hasOwnProperty(i)) { + result[i] = getIndex(value[i]); } } - result = {}; + return result; } - keys.forEach(function (key) { - result[key] = getIndex(value[key]); - }); + for (var typeName in customTypes) { + var args = asType(value, typeName); + if (args) { + return args; + } + } + + return asType(value, "o", true); } return result; @@ -111,17 +116,6 @@ function toTable(value) { return table; } -function isPlainObject(value) { - var isObject = value && typeof value === "object"; - if (isObject) { - var proto = Object.getPrototypeOf - ? Object.getPrototypeOf(value) - : value.__proto__; - return proto === Object.prototype; - } - return false; -} - function makeGetIndexFunction(values) { var indexMap = typeof Map === "function" && new Map;