How to define method in javascript on Array.prototype and Object.prototype so that it doesn’t appear in for in loop

It’s quite easy: Don’t use for-in loops with Arrays. Blame everybody else who does so – here is a nice snippet to tell them during development.

Of course, if one does an enumeration in a generic function and doesn’t know whether he gets an array, a plain object or an object with a custom prototype, you can use hasOwnProperty like this:

for (var prop in anyObj )
    if (Object.prototype.hasOwnProperty.call(anyObj, prop))
        // do something

Notice the explicit use of Object.prototype to get the function – there might be objects that overwrite it (especially in data-maps, the value might not even be a function), objects that do not support it or objects that do not inherit from Object.prototype at all. See also here.

Yet, only a script author who is aware of the problem would filter all his for-in-loops – and some only do it because it gets recommended – and does it mostly wrong, he should have used a for-loop array iteration instead. But our problem are those authors who do not know of it.

An interesting, but Mozilla-only approach would be overwriting the behavior of enumerations on arrays via __iterate__, as demonstrated here.

Fortunately, EcmaScript 5.1 allows us setting properties to be non-enumerable. Of course, this is not supported in older browsers, but why bother? We’d need to use es5-shims anyway for all the cool higher-order array stuff 🙂 Use defineProperty like this:

Object.defineProperty(Array.prototype, "find", {
    enumerable: false,
    writable: true,
    value: function(testFun) {
        // code to find element in array
    }
});

Leave a Comment