SoreThumb
SoreThumb

Reputation: 530

Adding function to Object prototype causes function to show up in all 'for X in OBJ' loops

So, here's some sample javascript code:

Object.prototype.simpleFunction = function () {
    return true;
}
var tempObject = {};
for (var temp in tempObject) {
    console.log(temp);
}

Note that if you execute this, you'll get 'simpleFunction' output from the console.log commands in Google Chrome. (I'm using 19.0.1084.46m .)

However, the wide variety of related Object functions are not passed to the console.log.

How can I add functions onto the Object prototype without them showing up in my 'for property in object' loops?

Edit: I should have mentioned that the last thing I wanted was to throw another 'if' statement in there, as it'd mean I'd need to add it to ALL for loops. :(

Upvotes: 9

Views: 13077

Answers (4)

Joseph Silber
Joseph Silber

Reputation: 220026

Which is why you should always check hasOwnProperty:

for (var temp in tempObject) {
    if (Object.prototype.hasOwnProperty(tempObject, temp)) {
        console.log(temp);
    }
}

Crockford advocates using Object.prototype.hasOwnProperty instead of tempObject.hasOwnProperty, just in case you override hasOwnProperty in your object.


In ES5, you can set it to not be enumerable:

Object.defineProperty(Object.prototype, 'simpleFunction', {
    value: function() {
        return true;
    },
    enumerable: false, // this is actually the default
});

Alternatively (in ES5), you can use Object.keys() to only get the object's own keys:

Object.keys(tempObject).forEach(function(key) {
    console.log(key);
});

Upvotes: 15

Ja͢ck
Ja͢ck

Reputation: 173642

You can skip the inherited properties by doing this:

if (tempObject.hasOwnProperty(temp)) {
    // property didn't come from the prototype chain
}

The bottom line is, you can't add functions to the prototype without having them being iterated using in.

You could define an external interface in which you always pass the object, e.g.

function simpleFunction(obj) {
}

Upvotes: 0

supNate
supNate

Reputation: 430

It's not possible to do this in javascript. You need to filter the results yourself. One potential method is to define your own prototype properties in another object:

var myObjectExt = {
    sampleFunciton: function(){}
}
var p;
for(p in myObjectExt){
    Object.prototype[p] = myObjectExt[p];
}

var obj = {};
for(p in obj){
    if(myObjectExt[p])continue;
    //do what you need
}

Upvotes: 0

Sudhir Bastakoti
Sudhir Bastakoti

Reputation: 100195

Do you mean something like:

for (var temp in tempObject) {
    if (tempObject.hasOwnProperty(temp )) {
         console.log(temp);
    }
}

Upvotes: 0

Related Questions