Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript custom Array.prototype interfering with for-in loops

Tags:

javascript

I was attempting to extend Javascript's Object type with a function that retrieves all of the property names that are part of that object (basically what PHP's array_keys() function does to associative arrays).

Object.prototype.keys = function() {
    var a = [];
    for (var property in this) {
        a.push(property);
    }
    return a;
};

var a = {a:1,b:2,c:3,d:4};
alert(a.toSource());

var b = a.keys();
alert(b.toSource());

When the variable b was alerted, I was expecting to see ["a","b","c","d"], instead I'm seeing ["a","b","c","d","keys"].

It appears the for-in loop is including the prototyped keys() functions.

Is it possible to avoid this behaviour whilst still prototying, or should I just avoid prototyping all together?

like image 702
Lachlan McDonald Avatar asked Dec 03 '22 07:12

Lachlan McDonald


1 Answers

Ahh the joys of extending the built-ins. for..in checks up the entire prototype chain of the object being iterated.

What you need (and I believe this is de-facto now) is a check with hasOwnProperty in your loop:

for (var property in this) {
    if (this.hasOwnProperty(property)) {
        a.push(property);
    }
}

hasOwnProperty ensures that you only get properties that are directly defined on your object (i.e. not up the prototype chain).

like image 72
Roatin Marth Avatar answered May 25 '23 06:05

Roatin Marth