UNPKG

sinon

Version:

JavaScript test spies, stubs and mocks.

50 lines (42 loc) 1.83 kB
"use strict"; 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, {}); };