I was trying to find the fastest way of running a for loop with its own scope. The three methods I compared were:
var a = \"t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t
Yes, lodash/underscore each don't even have same semantics as .forEach. There is a subtle detail that will make the function really slow unless the engine can check for sparse arrays without getters quickly.
This will be 99% spec compliant and runs at the same speed as lodash each in V8 for the common case:
function FastAlmostSpecForEach( fn, ctx ) {
"use strict";
if( arguments.length > 1 ) return slowCaseForEach();
if( typeof this !== "object" ) return slowCaseForEach();
if( this === null ) throw new Error("this is null or not defined");
if( typeof fn !== "function" ) throw new Error("is not a function");
var len = this.length;
if( ( len >>> 0 ) !== len ) return slowCaseForEach();
for( var i = 0; i < len; ++i ) {
var item = this[i];
//Semantics are not exactly the same,
//Fully spec compliant will not invoke getters
//but this will.. however that is an insane edge case
if( item === void 0 && !(i in this) ) {
continue;
}
fn( item, i, this );
}
}
Array.prototype.fastSpecForEach = FastAlmostSpecForEach;
By checking for undefined first, we don't punish normal arrays in the loop at all. An engine could use its internals to detect strange arrays but V8 doesn't.