Search code examples
javascriptjqueryobjectfiltering

JavaScript: filter() for Objects


ECMAScript 5 has the filter() prototype for Array types, but not Object types, if I understand correctly.

How would I implement a filter() for Objects in JavaScript?

Let's say I have this object:

var foo = {
    bar: "Yes"
};

And I want to write a filter() that works on Objects:

Object.prototype.filter = function(predicate) {
    var result = {};

    for (key in this) {
        if (this.hasOwnProperty(key) && !predicate(this[key])) {
            result[key] = this[key];
        }
    }

    return result;
};

This works when I use it in the following demo, but when I add it to my site that uses jQuery 1.5 and jQuery UI 1.8.9, I get JavaScript errors in FireBug.

Object.prototype.filter = function(predicate) {
  var result = {};
  for (key in this) {
    if (this.hasOwnProperty(key) && !predicate(this[key])) {
      console.log("copying");
      result[key] = this[key];
    }
  }
  return result;
};

var foo = {
  bar: "Yes",
  moo: undefined
};

foo = foo.filter(function(property) {
  return typeof property === "undefined";
});

document.getElementById('disp').innerHTML = JSON.stringify(foo, undefined, '  ');
console.log(foo);
#disp {
  white-space: pre;
  font-family: monospace
}
<div id="disp"></div>


Solution

  • Never ever extend Object.prototype.

    Horrible things will happen to your code. Things will break. You're extending all object types, including object literals.

    Here's a quick example you can try:

        // Extend Object.prototype
    Object.prototype.extended = "I'm everywhere!";
    
        // See the result
    alert( {}.extended );          // "I'm everywhere!"
    alert( [].extended );          // "I'm everywhere!"
    alert( new Date().extended );  // "I'm everywhere!"
    alert( 3..extended );          // "I'm everywhere!"
    alert( true.extended );        // "I'm everywhere!"
    alert( "here?".extended );     // "I'm everywhere!"
    

    Instead create a function that you pass the object.

    Object.filter = function( obj, predicate) {
        let result = {}, key;
    
        for (key in obj) {
            if (obj.hasOwnProperty(key) && !predicate(obj[key])) {
                result[key] = obj[key];
            }
        }
    
        return result;
    };