lib/libs.js
function each (o, rangeA, rangeB, f) {

                    // Can't use last here.. would cause circular ref...
                    f = undefined;
                    for(var k = arguments.length - 1; k >= 0; k--) {
                        if(arguments[k] instanceof Function) {
                            f = arguments[k];
                            break;
                        }
                    }

                    var ret    = null,
                        broken = false,
                        self   = o,
                        keys, property, value,

                        exit = function () {
                            broken   = true;
                            ret      = arguments.length > 1 ? libs.object.toArray(arguments) : arguments[0];
                        };

                    if(f instanceof Function) {
                        if(typeof self === 'number' || typeof self === 'function' || typeof self === 'boolean') self = o.toString();

                        // Firefox does some funky stuff here...
                        if(typeof o === 'function') self = fixFirefoxFunctionString(self);

                        // For Safari
                        var isArgs = Object.prototype.toString.call(o) === '[object Arguments]', idx = -1;
                        keys = getKeys(self);
                        idx  = keys.indexOf('length');

                        if(isArgs && idx > -1) keys.splice(idx, 1);

                        rangeA = parseInt(rangeA);
                        rangeA = (isNaN(rangeA) || !isFinite(rangeA)) ? 0 : rangeA;

                        rangeB = parseInt(rangeB);
                        rangeB = (isNaN(rangeB) || !isFinite(rangeB)) ? keys.length : rangeB;

                        var i = 0, n;
                        if(Math.abs(rangeA) > Math.abs(rangeB)) {
                            if(rangeB < 0) rangeB = 0;
                            if(rangeA < 0) rangeA = 0;
                            if(rangeA > keys.length - 1) rangeA = keys.length - 1;

                            for(n = rangeA; n >= rangeB; n--) {
                                property = keys[n];
                                value    = (typeof o === 'number' && !isNaN(parseFloat(self[property]))) ? parseFloat(self[property]) : self[property];
                                f.call(o, value, property, n, exit, i++, o);
                                if(broken) break;
                            }
                        }
                        else {
                            rangeB = rangeB + 1 > keys.length ? keys.length : rangeB + 1;
                            if(rangeB < 0) rangeB = 0;
                            if(rangeA < 0) rangeA = 0;

                            for(n = rangeA; n < rangeB; n++) {
                                property = keys[n];
                                value    = (typeof o === 'number' && !isNaN(parseFloat(self[property]))) ? parseFloat(self[property]) : self[property];
                                f.call(o, value, property, n, exit, i++, o);
                                if(broken) break;
                            }
                        }
                    }
                    return ret;
                }
function each (o, rangeA, rangeB, f) {

                    // Can't use last here.. would cause circular ref...
                    f = undefined;
                    for(var k = arguments.length - 1; k >= 0; k--) {
                        if(arguments[k] instanceof Function) {
                            f = arguments[k];
                            break;
                        }
                    }

                    var ret    = null,
                        broken = false,
                        self   = o,
                        keys, property, value,

                        exit = function () {
                            broken   = true;
                            ret      = arguments.length > 1 ? libs.object.toArray(arguments) : arguments[0];
                        };

                    if(f instanceof Function) {
                        if(typeof self === 'number' || typeof self === 'function' || typeof self === 'boolean') self = o.toString();

                        // Firefox does some funky stuff here...
                        if(typeof o === 'function') self = fixFirefoxFunctionString(self);

                        // For Safari
                        var isArgs = Object.prototype.toString.call(o) === '[object Arguments]', idx = -1;
                        keys = getKeys(self);
                        idx  = keys.indexOf('length');

                        if(isArgs && idx > -1) keys.splice(idx, 1);

                        rangeA = parseInt(rangeA);
                        rangeA = (isNaN(rangeA) || !isFinite(rangeA)) ? 0 : rangeA;

                        rangeB = parseInt(rangeB);
                        rangeB = (isNaN(rangeB) || !isFinite(rangeB)) ? keys.length : rangeB;

                        var i = 0, n;
                        if(Math.abs(rangeA) > Math.abs(rangeB)) {
                            if(rangeB < 0) rangeB = 0;
                            if(rangeA < 0) rangeA = 0;
                            if(rangeA > keys.length - 1) rangeA = keys.length - 1;

                            for(n = rangeA; n >= rangeB; n--) {
                                property = keys[n];
                                value    = (typeof o === 'number' && !isNaN(parseFloat(self[property]))) ? parseFloat(self[property]) : self[property];
                                f.call(o, value, property, n, exit, i++, o);
                                if(broken) break;
                            }
                        }
                        else {
                            rangeB = rangeB + 1 > keys.length ? keys.length : rangeB + 1;
                            if(rangeB < 0) rangeB = 0;
                            if(rangeA < 0) rangeA = 0;

                            for(n = rangeA; n < rangeB; n++) {
                                property = keys[n];
                                value    = (typeof o === 'number' && !isNaN(parseFloat(self[property]))) ? parseFloat(self[property]) : self[property];
                                f.call(o, value, property, n, exit, i++, o);
                                if(broken) break;
                            }
                        }
                    }
                    return ret;
                }
function each ( o , rangeA , rangeB , f ) { // Can't use last here.. would cause circular ref... f = undefined ; for ( var k = arguments . length - 1 ; k >= 0 ; k -- ) { if ( arguments [ k ] instanceof Function ) { f = arguments [ k ] ; break ; } } var ret = null , broken = false , self = o , keys , property , value , exit = function ( ) { broken = true ; ret = arguments . length > 1 ? libs . object . toArray ( arguments ) : arguments [ 0 ] ; } ; if ( f instanceof Function ) { if ( typeof self === 'number' || typeof self === 'function' || typeof self === 'boolean' ) self = o . toString ( ) ; // Firefox does some funky stuff here... if ( typeof o === 'function' ) self = fixFirefoxFunctionString ( self ) ; // For Safari var isArgs = Object . prototype . toString . call ( o ) === '[object Arguments]' , idx = - 1 ; keys = getKeys ( self ) ; idx = keys . indexOf ( 'length' ) ; if ( isArgs && idx > - 1 ) keys . splice ( idx , 1 ) ; rangeA = parseInt ( rangeA ) ; rangeA = ( isNaN ( rangeA ) || ! isFinite ( rangeA ) ) ? 0 : rangeA ; rangeB = parseInt ( rangeB ) ; rangeB = ( isNaN ( rangeB ) || ! isFinite ( rangeB ) ) ? keys . length : rangeB ; var i = 0 , n ; if ( Math . abs ( rangeA ) > Math . abs ( rangeB ) ) { if ( rangeB < 0 ) rangeB = 0 ; if ( rangeA < 0 ) rangeA = 0 ; if ( rangeA > keys . length - 1 ) rangeA = keys . length - 1 ; for ( n = rangeA ; n >= rangeB ; n -- ) { property = keys [ n ] ; value = ( typeof o === 'number' && ! isNaN ( parseFloat ( self [ property ] ) ) ) ? parseFloat ( self [ property ] ) : self [ property ] ; f . call ( o , value , property , n , exit , i ++ , o ) ; if ( broken ) break ; } } else { rangeB = rangeB + 1 > keys . length ? keys . length : rangeB + 1 ; if ( rangeB < 0 ) rangeB = 0 ; if ( rangeA < 0 ) rangeA = 0 ; for ( n = rangeA ; n < rangeB ; n ++ ) { property = keys [ n ] ; value = ( typeof o === 'number' && ! isNaN ( parseFloat ( self [ property ] ) ) ) ? parseFloat ( self [ property ] ) : self [ property ] ; f . call ( o , value , property , n , exit , i ++ , o ) ; if ( broken ) break ; } } } return ret ; }
Invokes the callback 'f' for each property the object contains. If this is called
on a number or function, the object will be cast to a string.<br><br>
The callback `f` will be invoked with the following arguments:
<ul>
<li>value     - The value of the current object being iterated over</li>
<li>key       - The key of the current object (if an object, the index if an array)</li>
<li>iteration - The current iteration (same as key if a string or array)</li>
<li>exit      - A function which will break the loop and return the values passed to it,
or a single value if only a single value is passed.</li>
</ul>
@function
@param {Object} o The object to operate on.
@param {Number=} [rangeA=0] The iteration start index
@param {Number=} [rangeB='length of the item'] The iteration end index
@param {Function} f The callback to invoke for each item within the object
@returns {*} The value passed to the exit parameter of the callback...
Invokes the callback f for each property the object contains . If this is called on a number or function the object will be cast to a string . <br > <br > The callback f will be invoked with the following arguments : <ul > <li > value - The value of the current object being iterated over< / li > <li > key - The key of the current object ( if an object the index if an array ) < / li > <li > iteration - The current iteration ( same as key if a string or array ) < / li > <li > exit - A function which will break the loop and return the values passed to it or a single value if only a single value is passed . < / li > < / ul >