To filter entries which aren't strictly arrays, and thus don't have the .filter property on their prototype, but are still iterable (like document.getElementsByTagName), you can use
Array.prototype.filter.call(collection, function filterFunction(el, index, collection) {
...
});
Or the shorthand
[].filter.call(collection, function filterFunction(el, index, collection) {
...
});
As for objects which are not iterable, but you still want to filter properties and get an array of keys that pass filtering, you can combine with Object.keys like so:
var obj = { one: 1, two: 2, three: 3, four: 4 };
var filtered = Object.keys(obj).filter(function(key) {
return obj[key] % 2 === 0;
}); //filtered == ['two', 'four']
Then, you can create a new object containing those properties:
var filteredObj = filtered.reduce(function(newObj, currentKey) {
newObj[currentKey] = obj[currentKey]; //Add the original value to the new object
return newObj; //Return the new object to continue iteration
}, {}) // Begin iteration with a blank object
//filteredObj is now { two: 2, four: 4 }
The above can even be combined into a function!
function filterObject(obj, testCallback) {
return Object.keys(obj).filter(function(key, index, array) {
return testCallback(obj[key], index, array); //Call original filter but pass the property
}).reduce(function(newObj, currentKey) {
newObj[currentKey] = obj[currentKey]; //Add the original value to the new object
return newObj; //Return the new object to continue iteration
}, {}); // Begin iteration with a blank object
}
And use like this:
var obj = { one: 1, two: 2, three: 3, four: 4 };
var filteredObj = filterObject(obj, function(el) { return el % 2 === 0 });