I am trying to create a recursive function that filters an object, depending on the properties in the second passed argument.
Filtering works well, but my arrays are being replaced with empty objects. What could I do different so that this doesn’t occur?
var filter = function(obj, fields) {
var key, o;
if (typeof obj !== "object") { return obj;}
o = {};
for (key in obj) {
if (fields[key]) {
o[key] = filter(obj[key], fields[key]);
}
}
return o;
};
data = {name: "John Doe", followers: [], notAllowedProp: false}
allowedFields = {name: true, followers: true}
console.log(filter(data, allowedFields));
// => Object { name: "John Doe", followers: {}}
-
you are returning an empty object regardless of the fields type I suggest checking the filed type and initiating o by it.AMember– AMember2012年10月16日 17:11:16 +00:00Commented Oct 16, 2012 at 17:11
2 Answers 2
Try this on a console:
> typeof []
"object"
To check for an array more robustly, you can use Object.prototype.toString:
> Object.prototype.toString.call([])
"[object Array]"
Object.prototype.toString has well-defined behavior for all native objects, and is quite reliable. Thus, for example, if you want to return anything that is not a "true" object, you could write:
if (Object.prototype.toString(obj) !== "[object Object]") {
return obj;
}
10 Comments
[].constructor === Array.Object.prototype.toString.instanceof.Object.prototype.toString regardless. And from another standpoint, I'd argue that Object.prototype.toString is more readable than manipulating typeof and instanceof.Arrays have type object. Consequently, you'll need to edit this line if you want to return early for arrays:
if (typeof obj !== "object") { return obj; }
There are many ways to check for an array, but this is what I would do:
if(typeof obj !== "object" && !(obj instanceof Array)) { return obj; }