Take the 2-minute tour ×

I've tried to add some new functions to the Array prototype, that I use frequently. My question is how when I add something to the prototype of an Object, and trace out properties in a for-in loop of any new array (object) that I created, those new functions that were added only to the prototype are listed as well? Shouldn't they just be in proto?

Just for example: So I add an function of "first" to the prototype.

Array.prototype.first = function() { return this[0]; }

So when now I use an for-in loop to iterate over the array, I get the named function, as well as any other items that are in the array.

var array = [1,2,3];   

//traces out: 1,3,4,first
for(var i in array) {

Is this something that is solely resulting from the trace and/or use of for-in for iterating over an object?

share|improve this question
add comment

3 Answers

up vote 2 down vote accepted

Evan is correct. However, when using for..in statements in javascript, it is always best to test that the current attribute is a property of the object and not something inherited from the prototype chain:

for(var attr in obj){
       // first will not appear here
share|improve this answer
Ah, I see. So using an hasOwnProperty() to check only for properties vs. inherited from the prototype chain. Thanks for the response Rob. –  listao Nov 18 '13 at 23:24
My pleasure, this is something a lot of people find confusing. Maurice is also correct in saying that extending the prototype of native js objects is considered bad practice. en.wikipedia.org/wiki/Prototype_JavaScript_Framework#Problems –  Rob M. Nov 18 '13 at 23:27
And here I was about to add a bunch of prototypes to Array, String and Date. If you make them non-enumerable though, as in Maurice's answer, what is the real danger in adding prototypes to native Objects? I guess that if you extended the prototype with the same function names as others as in an included library, then would the original be overwritten or something? That's the only thing that comes to mind. –  Chris Cirefice Nov 18 '13 at 23:31
Name collisions are one of the main problems, it also can add a significant amount of overhead depending on what you extend. An in depth article on this subject can be found here: perfectionkills.com/whats-wrong-with-extending-the-dom –  Rob M. Nov 18 '13 at 23:39
add comment

You shouldn't use a for-in loop to loop over an array.

for (var i = 0, len = arr.length; i < len; ++i) {

for in is used for iterating the keys of an object.

share|improve this answer
Why not? (legitimate question) –  Darkhogg Nov 18 '13 at 23:08
Makes sense to use an for-loop to iterate over arrays, but if I was to iterate over an object, I assume it would still print out the same thing. –  listao Nov 18 '13 at 23:14
Because when you augment the array prototype you'll get those extra properties. Also, it's quite a bit faster: jsperf.com/forin-forlength –  Evan Trimboli Nov 18 '13 at 23:15
Evan, thanks for the reply, and the link to the performance test. –  listao Nov 18 '13 at 23:26
add comment

If you really need to do this, use

Object.defineProperty(Array.prototype, 'first', {
    value: function() { return this[0]; },
    enumerable: false

But some consider this a bad practice. Think twice before doing it.

share|improve this answer
Thanks Maurice for pointing that out, and the alternative way to do it if need-be. –  listao Nov 18 '13 at 23:31
As for the reasons why not to do it: 1. Usually the for in breaks (you fixed but not all browsers support it and can't be polyfilled). 2. Conflict with future browser implementation or other code. –  HMR Nov 19 '13 at 3:47
@leetou the alternative way would be to just create a function named first and invoke it like this: first.call(someArray); Maybe the following link will be helpful to you: stackoverflow.com/a/16063711/1641941 –  HMR Nov 19 '13 at 3:48
add comment

Your Answer


