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> |
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
indexOfmethod is 1.
Thanks. I shortened this a bit, though.