sugar
Version:
A Javascript utility library for working with native objects.
54 lines (44 loc) • 1.42 kB
JavaScript
;
var getKeys = require('./getKeys'),
coreUtilityAliases = require('../var/coreUtilityAliases');
var forEachProperty = coreUtilityAliases.forEachProperty;
function iterateWithCyclicCheck(obj, sortedKeys, stack, fn) {
function next(val, key) {
var cyc = false;
// Allowing a step into the structure before triggering this check to save
// cycles on standard JSON structures and also to try as hard as possible to
// catch basic properties that may have been modified.
if (stack.length > 1) {
var i = stack.length;
while (i--) {
if (stack[i] === val) {
cyc = true;
}
}
}
stack.push(val);
fn(key, val, cyc, stack);
stack.pop();
}
function iterateWithSortedKeys() {
// Sorted keys is required for serialization, where object order
// does not matter but stringified order does.
var arr = getKeys(obj).sort(), key;
for (var i = 0; i < arr.length; i++) {
key = arr[i];
next(obj[key], arr[i]);
}
}
// This method for checking for cyclic structures was egregiously stolen from
// the ingenious method by @kitcambridge from the Underscore script:
// https://github.com/documentcloud/underscore/issues/240
if (!stack) {
stack = [];
}
if (sortedKeys) {
iterateWithSortedKeys();
} else {
forEachProperty(obj, next);
}
}
module.exports = iterateWithCyclicCheck;