diff --git a/lib/jsdoc/util/dumper.js b/lib/jsdoc/util/dumper.js index fd65a9e2..317268c6 100644 --- a/lib/jsdoc/util/dumper.js +++ b/lib/jsdoc/util/dumper.js @@ -7,17 +7,43 @@ 'use strict'; var util = require('util'); +var setDefined = typeof Set !== 'undefined'; function ObjectWalker() { - this.seenItems = []; + if (setDefined) { + this.seenItems = new Set(); + } else { + this.seenItems = []; + } } ObjectWalker.prototype.seen = function(object) { - if (this.seenItems.indexOf(object) !== -1) { - return true; + var result; + if (setDefined) { + result = this.seenItems.has(object); + } else { + result = object.hasBeenSeenByWalkerDumper; } + return result; +}; - return false; +ObjectWalker.prototype.markAsSeen = function(object) { + if (setDefined) { + this.seenItems.add(object); + } else { + object.hasBeenSeenByWalkerDumper = true; + this.seenItems.push(object); + } +}; + +ObjectWalker.prototype.cleanSeenFlag = function() { + if (setDefined) { + this.seenItems = new Set(); + } else { + this.seenItems.forEach(function(object) { + delete object.hasBeenSeenByWalkerDumper; + }); + } }; // some objects are unwalkable, like Java native objects @@ -39,7 +65,7 @@ ObjectWalker.prototype.checkCircularRefs = function(o, func) { return ''; } else { - this.seenItems.push(o); + this.markAsSeen(o); return func(o); } }; @@ -81,6 +107,7 @@ ObjectWalker.prototype.walk = function(o) { result = this.checkCircularRefs(o, function(obj) { var newObj = {}; Object.keys(obj).forEach(function(key) { + if (!setDefined && key === 'hasBeenSeenByWalkerDumper') { return; } newObj[key] = self.walk(obj[key]); }); @@ -99,5 +126,9 @@ ObjectWalker.prototype.walk = function(o) { * @param {*} object */ exports.dump = function(object) { - return JSON.stringify(new ObjectWalker().walk(object), null, 4); + var walker = new ObjectWalker(); + var result = JSON.stringify(walker.walk(object), null, 4); + walker.cleanSeenFlag(); + + return result; };