component-each
Version:
Array / object / string iteration utility
90 lines (76 loc) • 1.51 kB
JavaScript
/**
* Module dependencies.
*/
try {
var type = require('type');
} catch (err) {
var type = require('component-type');
}
var toFunction = require('to-function');
/**
* HOP reference.
*/
var has = Object.prototype.hasOwnProperty;
/**
* Iterate the given `obj` and invoke `fn(val, i)`
* in optional context `ctx`.
*
* @param {String|Array|Object} obj
* @param {Function} fn
* @param {Object} [ctx]
* @api public
*/
module.exports = function(obj, fn, ctx){
fn = toFunction(fn);
ctx = ctx || this;
switch (type(obj)) {
case 'array':
return array(obj, fn, ctx);
case 'object':
if ('number' == typeof obj.length) return array(obj, fn, ctx);
return object(obj, fn, ctx);
case 'string':
return string(obj, fn, ctx);
}
};
/**
* Iterate string chars.
*
* @param {String} obj
* @param {Function} fn
* @param {Object} ctx
* @api private
*/
function string(obj, fn, ctx) {
for (var i = 0; i < obj.length; ++i) {
fn.call(ctx, obj.charAt(i), i);
}
}
/**
* Iterate object keys.
*
* @param {Object} obj
* @param {Function} fn
* @param {Object} ctx
* @api private
*/
function object(obj, fn, ctx) {
for (var key in obj) {
if (has.call(obj, key)) {
fn.call(ctx, key, obj[key]);
}
}
}
/**
* Iterate array-ish.
*
* @param {Array|Object} obj
* @param {Function} fn
* @param {Object} ctx
* @api private
*/
function array(obj, fn, ctx) {
for (var i = 0; i < obj.length; ++i) {
fn.call(ctx, obj[i], i);
}
}