/** * Obliterator ForEach Function * ============================= * * Helper function used to easily iterate over mixed values. */ var support = require('./support.js'); var ARRAY_BUFFER_SUPPORT = support.ARRAY_BUFFER_SUPPORT; var SYMBOL_SUPPORT = support.SYMBOL_SUPPORT; /** * Function able to iterate over almost any iterable JS value. * * @param {any} iterable - Iterable value. * @param {function} callback - Callback function. */ module.exports = function forEach(iterable, callback) { var iterator, k, i, l, s; if (!iterable) throw new Error('obliterator/forEach: invalid iterable.'); if (typeof callback !== 'function') throw new Error('obliterator/forEach: expecting a callback.'); // The target is an array or a string or function arguments if ( Array.isArray(iterable) || (ARRAY_BUFFER_SUPPORT && ArrayBuffer.isView(iterable)) || typeof iterable === 'string' || iterable.toString() === '[object Arguments]' ) { for (i = 0, l = iterable.length; i < l; i++) callback(iterable[i], i); return; } // The target has a #.forEach method if (typeof iterable.forEach === 'function') { iterable.forEach(callback); return; } // The target is iterable if ( SYMBOL_SUPPORT && Symbol.iterator in iterable && typeof iterable.next !== 'function' ) { iterable = iterable[Symbol.iterator](); } // The target is an iterator if (typeof iterable.next === 'function') { iterator = iterable; i = 0; while (((s = iterator.next()), s.done !== true)) { callback(s.value, i); i++; } return; } // The target is a plain object for (k in iterable) { if (iterable.hasOwnProperty(k)) { callback(iterable[k], k); } } return; };