All that Array.prototype.filter
really requires is that the variable being iterated over has a length
property, and that the variable has numeric-indexed values. See (part of) the polyfill:
var len = this.length >>> 0,
res = new Array(len), // preallocate array
t = this, c = 0, i = -1;
if (thisArg === undefined){
while (++i !== len){
// checks to see if the key was set
if (i in this){
if (func(t[i], i, t)){
res[c++] = t[i];
}
}
}
}
Strings fulfill this condition - strings have a length
property, and numeric indicies accessed on the string resolve to individual characters.
But you can do the same thing with arbitrary objects:
const obj = {
0: 'foo',
1: 'bar',
length: 2
};
const result = [].filter.call(obj, val => val.startsWith('f'));
console.log(result);
You could say that obj
is array-like as well, since it has a length
property and numeric indicies. Most array methods like .filter
, .reduce
, etc can be .call
ed on array-like objects, even if those objects aren't actual arrays.
(Technically, you can also call array methods on non-array-like objects too, it just won't do anything useful - no iterations may be performed)