A tweet-sized ES5-compatible polyfill for Array.prototype.indexOf
-
-
Save atk/1034425 to your computer and use it in GitHub Desktop.
// Avoid overwriting prototype if not neccessary | |
[].indexOf||(Array.prototype.indexOf= | |
function( | |
a, // search item | |
b, // startIndex and/or counter | |
c // length placeholder | |
) { | |
for ( | |
// initialize length | |
var c = this.length, | |
// initialize counter (allow for negative startIndex) | |
b = (c + ~~b) % c | |
// loop if index is smaller than length, | |
// index is set in (possibly sparse) array | |
// and item at index is not identical to the searched one | |
b < c && (!(b in this || this[b] !== a)); | |
// increment counter | |
b++ | |
); | |
// if counter equals length (not found), return -1, otherwise counter | |
return b ^ c ? b : -1; | |
}) |
[].indexOf||(Array.prototype.indexOf=function(a,b,c){for(c=this.length,b=(c+~~b)%c;b<c&&(!(b in this)||this[b]!==a);b++);return b^c?b:-1;}) |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
Version 2, December 2004 | |
Copyright (C) 2011 Alex Kloss <[email protected]> | |
Everyone is permitted to copy and distribute verbatim or modified | |
copies of this license document, and changing it is allowed as long | |
as the name is changed. | |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |
0. You just DO WHAT THE FUCK YOU WANT TO. |
{ | |
"name": "indexOf", | |
"description": "polyfill an ES5-compatibile Array.prototype.indexOf where needed.", | |
"keywords": [ | |
"array", | |
"indexof", | |
"es5", | |
"polyfill" | |
] | |
} |
<!DOCTYPE html> | |
<title>Foo</title> | |
<div>Expected value: <b>0,1,2,-1</b></div> | |
<div>Actual value: <b id="ret"></b></div> | |
<script> | |
var indexOf = | |
[].indexOf||(Array.prototype.indexOf=function(a,b,c){for(var b=b|0,c=this.length;b<c&&(!(b in this||this[b]!==a));b++);return b^c?-1:b;}) | |
var testdata=[1,2,3,5]; | |
document.getElementById( "ret" ).innerHTML = [indexOf.call(testdata,1), indexOf.call(testdata,2), indexOf.call(testdata,3), indexOf.call(testdata,4)]; | |
</script> |
I knew it was too easy. Standby for corrected version :-)
while you're at it, also try implementing the optional fromIndex.
One at a time, my friend. Always one at a time :-) Corrected version is up.
Though my last version could dub as lastIndexOf :-)
@Kambfhase : If I get it right, fromIndex is another argument limiting the start/end of these methods?
yes, fromIndex
specify the beginning of the search : https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf#section_3
something like this should work :
Array.prototype.indexOf=function(a,f){for(var c=this.length,r=-1,d=f>>>0;~(c-d);r=this[--c]===a?c:r);return r}
Thanks. I shortened this a bit, though.
sorry @atk, this package.json
is invalid too, because of the trailing keywords comma.
Despite the description, polyfill an ES5-compatible Array.prototype.indexOf
, this is not an ES5 compatible fallback because it lacks sparse array support and resolves the length
incorrectly. Also browsers like Chrome have a bug where Array.prototype.indexOf = [].indexOf
will cause Array#indexOf
to become enumerable.
Hi @atk
In the first version(with startIndex), you should move the ++increment to the repeatingExpression.
Try [1,2].indexOf(1)
.
This should be better :-)
This doesn't handle negative fromIndex
's correctly.
Thanks, I'm working on it.
Update: works now.
Doesn't handle when the negative fromIndex plus the length result in less than 0;
See step 8b
annotated.js line 16 has incorrect parentheses:
b < c && (!(b in this || this[b] !== a));
should be:
b < c && (!(b in this) || this[b] !== a);
This polyfill function has the wrong arity. The spec states:
The length property of the
indexOf
method is 1.
To be fully ES5-compatible you need to iterate from left to right: