sinon
Version:
JavaScript test spies, stubs and mocks.
50 lines (42 loc) • 1.83 kB
JavaScript
const forEach = require("@sinonjs/commons").prototypes.array.forEach;
function walkInternal(obj, iterator, context, originalObj, seen) {
let prop;
const proto = Object.getPrototypeOf(obj);
if (typeof Object.getOwnPropertyNames !== "function") {
// We explicitly want to enumerate through all of the prototype's properties
// in this case, therefore we deliberately leave out an own property check.
/* eslint-disable-next-line guard-for-in */
for (prop in obj) {
iterator.call(context, obj[prop], prop, obj);
}
return;
}
forEach(Object.getOwnPropertyNames(obj), function (k) {
if (seen[k] !== true) {
seen[k] = true;
const target =
typeof Object.getOwnPropertyDescriptor(obj, k).get ===
"function"
? originalObj
: obj;
iterator.call(context, k, target);
}
});
if (proto) {
walkInternal(proto, iterator, context, originalObj, seen);
}
}
/* Walks the prototype chain of an object and iterates over every own property
* name encountered. The iterator is called in the same fashion that Array.prototype.forEach
* works, where it is passed the value, key, and own object as the 1st, 2nd, and 3rd positional
* argument, respectively. In cases where Object.getOwnPropertyNames is not available, walk will
* default to using a simple for..in loop.
*
* obj - The object to walk the prototype chain for.
* iterator - The function to be called on each pass of the walk.
* context - (Optional) When given, the iterator will be called with this object as the receiver.
*/
module.exports = function walk(obj, iterator, context) {
return walkInternal(obj, iterator, context, obj, {});
};
;