Skip to content

Instantly share code, notes, and snippets.

@dcherman
Last active February 10, 2016 20:06
Show Gist options
  • Save dcherman/5167353 to your computer and use it in GitHub Desktop.
Save dcherman/5167353 to your computer and use it in GitHub Desktop.
Array.prototype.find and Array.prototype.findIndex polyfills based on the spec at https://gist.github.com/rwldrn/5079427
(function() {
function polyfill( fnName ) {
if ( !Array.prototype[fnName] ) {
Array.prototype[fnName] = function( predicate /*, thisArg */ ) {
var i, len, test, thisArg = arguments[ 1 ];
if ( typeof predicate !== "function" ) {
throw new TypeError();
}
test = !thisArg ? predicate : function() {
return predicate.apply( thisArg, arguments );
};
for( i = 0, len = this.length; i < len; i++ ) {
if ( test(this[i], i, this) === true ) {
return fnName === "find" ? this[ i ] : i;
}
}
if ( fnName !== "find" ) {
return -1;
}
};
}
}
for( var i in { find: 1, findIndex: 1 }) {
polyfill( i );
}
}());
@Dragiyski
Copy link

This does not work with the real speed of "find". Example:

var a = [];
a[10000] = 2;
a.find(function(v) { return v === 4; });

will iterate 10000 times by polyfill and only call callback once by real "find".
ECMAScript 5.1 has Array.prototype.some, so you can use it. Earlier version has no escape from iterating.

Array.prototype.find = function(predicate, thisArg) {
    "use strict";
    //TODO: Check predicate is a function.
    var lastValue;
    if(!Array.prototype.some.call(this, function(val, index, arr) {
        return predicate.call(thisArg, lastValue = val, index, arr);
    })) {
        return;
    }
    return lastValue;
}
Array.prototype.findIndex = function(predicate, thisArg) {
    "use strict";
    //TODO: Check predicate is a function.
    var lastIndex = -1;
    if(!Array.prototype.some.call(this, function(val, index, arr) {
        return predicate.call(thisArg, val, lastIndex = index, arr);
    })) {
        return -1;
    }
    return lastIndex;
}

Now the function speed matches the order of the real Array.prototype.find of ES6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment