[Pkg-javascript-commits] [json-js] 03/18: replacer

Jonas Smedegaard dr at jones.dk
Wed Aug 31 09:48:45 UTC 2016


This is an automated email from the git hooks/post-receive script.

js pushed a commit to branch master
in repository json-js.

commit ff3f6415b282220f13f85b52f92a1cc955caa2f2
Author: Douglas Crockford <douglas at crockford.com>
Date:   Sat May 7 10:39:50 2016 -0700

    replacer
---
 cycle.js | 134 ++++++++++++++++++++++++++++++++++-----------------------------
 1 file changed, 72 insertions(+), 62 deletions(-)

diff --git a/cycle.js b/cycle.js
index 0839437..7e00c5c 100644
--- a/cycle.js
+++ b/cycle.js
@@ -1,6 +1,6 @@
 /*
     cycle.js
-    2015-02-25
+    2016-05-01
 
     Public Domain.
 
@@ -15,60 +15,75 @@
 
 /*jslint eval, for */
 
-/*property 
-    $ref, apply, call, decycle, hasOwnProperty, length, prototype, push,
-    retrocycle, stringify, test, toString
+/*property
+    $ref, decycle, forEach, isArray, keys, length, push, retrocycle, stringify,
+    test
 */
 
-if (typeof JSON.decycle !== 'function') {
-    JSON.decycle = function decycle(object) {
-        'use strict';
+if (typeof JSON.decycle !== "function") {
+    JSON.decycle = function decycle(object, replacer) {
+        "use strict";
 
 // Make a deep copy of an object or array, assuring that there is at most
 // one instance of each object or array in the resulting structure. The
 // duplicate references (which might be forming cycles) are replaced with
 // an object of the form
-//      {$ref: PATH}
+
+//      {"$ref": PATH}
+
 // where the PATH is a JSONPath string that locates the first occurance.
+
 // So,
+
 //      var a = [];
 //      a[0] = a;
 //      return JSON.stringify(JSON.decycle(a));
+
 // produces the string '[{"$ref":"$"}]'.
 
+// If a replacer function is provided, then it will be called for each value.
+// A replacer function receives a value and returns a replacement value.
+
 // JSONPath is used to locate the unique object. $ indicates the top level of
-// the object or array. [NUMBER] or [STRING] indicates a child member or
+// the object or array. [NUMBER] or [STRING] indicates a child element or
 // property.
 
-        var objects = [],   // Keep a reference to each unique object or array
-            paths = [];     // Keep the path to each unique object or array
+        var objects = [];   // Keep a reference to each unique object or array
+        var paths = [];     // Keep the path to each unique object or array
 
         return (function derez(value, path) {
 
-// The derez recurses through the object, producing the deep copy.
+// The derez function recurses through the object, producing the deep copy.
+
+            var i;          // The loop counter
+            var nu;         // The new object or array
 
-            var i,          // The loop counter
-                name,       // Property name
-                nu;         // The new object or array
+// If a replacer function was provided, then call it to get a replacement value.
 
-// typeof null === 'object', so go on if this value is really an object but not
+            if (replacer !== undefined) {
+                value = replacer(value);
+            }
+
+// typeof null === "object", so go on if this value is really an object but not
 // one of the weird builtin objects.
 
-            if (typeof value === 'object' && value !== null &&
-                    !(value instanceof Boolean) &&
-                    !(value instanceof Date) &&
-                    !(value instanceof Number) &&
-                    !(value instanceof RegExp) &&
-                    !(value instanceof String)) {
+            if (
+                typeof value === "object" && value !== null &&
+                !(value instanceof Boolean) &&
+                !(value instanceof Date) &&
+                !(value instanceof Number) &&
+                !(value instanceof RegExp) &&
+                !(value instanceof String)
+            ) {
 
 // If the value is an object or array, look to see if we have already
-// encountered it. If so, return a $ref/path object. This is a hard way,
+// encountered it. If so, return a {"$ref":PATH} object. This is a hard
 // linear search that will get slower as the number of unique objects grows.
+// Someday, this should be replaced with an ES6 WeakMap.
 
-                for (i = 0; i < objects.length; i += 1) {
-                    if (objects[i] === value) {
-                        return {$ref: paths[i]};
-                    }
+                i = objects.indexOf(value);
+                if (i >= 0) {
+                    return {$ref: paths[i]};
                 }
 
 // Otherwise, accumulate the unique value and its path.
@@ -78,34 +93,34 @@ if (typeof JSON.decycle !== 'function') {
 
 // If it is an array, replicate the array.
 
-                if (Object.prototype.toString.apply(value) === '[object Array]') {
+                if (Array.isArray(value)) {
                     nu = [];
-                    for (i = 0; i < value.length; i += 1) {
-                        nu[i] = derez(value[i], path + '[' + i + ']');
-                    }
+                    value.forEach(function (element, i) {
+                        nu[i] = derez(element, path + "[" + i + "]");
+                    });
                 } else {
 
 // If it is an object, replicate the object.
 
                     nu = {};
-                    for (name in value) {
-                        if (Object.prototype.hasOwnProperty.call(value, name)) {
-                            nu[name] = derez(value[name],
-                                    path + '[' + JSON.stringify(name) + ']');
-                        }
-                    }
+                    Object.keys(value).forEach(function (name) {
+                        nu[name] = derez(
+                            value[name],
+                            path + "[" + JSON.stringify(name) + "]"
+                        );
+                    });
                 }
                 return nu;
             }
             return value;
-        }(object, '$'));
+        }(object, "$"));
     };
 }
 
 
-if (typeof JSON.retrocycle !== 'function') {
+if (typeof JSON.retrocycle !== "function") {
     JSON.retrocycle = function retrocycle($) {
-        'use strict';
+        "use strict";
 
 // Restore an object that was reduced by decycle. Members whose values are
 // objects of the form
@@ -135,35 +150,30 @@ if (typeof JSON.retrocycle !== 'function') {
 // replaces the $ref object with a reference to the value that is found by
 // the path.
 
-            var i, item, name, path;
-
-            if (value && typeof value === 'object') {
-                if (Object.prototype.toString.apply(value) === '[object Array]') {
-                    for (i = 0; i < value.length; i += 1) {
-                        item = value[i];
-                        if (item && typeof item === 'object') {
-                            path = item.$ref;
-                            if (typeof path === 'string' && px.test(path)) {
+            if (value && typeof value === "object") {
+                if (Array.isArray(value)) {
+                    value.forEach(function (element, i) {
+                        if (typeof element === "object" && element !== null) {
+                            var path = element.$ref;
+                            if (typeof path === "string" && px.test(path)) {
                                 value[i] = eval(path);
                             } else {
-                                rez(item);
+                                rez(element);
                             }
                         }
-                    }
+                    });
                 } else {
-                    for (name in value) {
-                        if (typeof value[name] === 'object') {
-                            item = value[name];
-                            if (item) {
-                                path = item.$ref;
-                                if (typeof path === 'string' && px.test(path)) {
-                                    value[name] = eval(path);
-                                } else {
-                                    rez(item);
-                                }
+                    Object.keys(value).forEach(function (name) {
+                        var item = value[name];
+                        if (typeof item === "object" && item !== null) {
+                            var path = item.$ref;
+                            if (typeof path === "string" && px.test(path)) {
+                                value[name] = eval(path);
+                            } else {
+                                rez(item);
                             }
                         }
-                    }
+                    });
                 }
             }
         }($));

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/json-js.git



More information about the Pkg-javascript-commits mailing list