2

I'd like to add an "insert" method on Arrays. So I'm doing it like this:

> Array.prototype.insert = function(index, element){
    this.splice(index, 0, element);
};

And it works:

> a = [1,2,3]
[1, 2, 3]
> a.insert(0, 4)
undefined
> a
[4, 1, 2, 3]

But there's an undesired side effect:

> for (i in a){console.log(i)}
0
1
2
3
insert

> for (i in a){console.log(a[i])}
4
1
2
3
function (index, element){
    this.splice(index, 0, element);
}

This behavior is not intended and breaks other libraries that I use. Is there any elegant solution for this?

p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
Tony Lâmpada
  • 5,301
  • 6
  • 38
  • 50
  • 6
    That's why you should never use `for..in` on an array. – James Montagne Mar 13 '14 at 18:33
  • 2
    You can still use the other construction of the `for` loop: `for ( var i = 0; i < a.length; i++ ) { console.log(a[i]); }` – Katie Kilian Mar 13 '14 at 18:34
  • Agreed! But nowadays we tend to reuse a lot of other people's code, and its hard to ensure that rule on all libs. – Tony Lâmpada Mar 13 '14 at 18:35
  • 2
    In fact, that's a great argument against doing what you're trying to do. Don't modify objects you don't own. http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/ – Katie Kilian Mar 13 '14 at 18:36
  • 1
    Relevant: http://stackoverflow.com/questions/8859828/javascript-what-dangers-are-in-extending-array-prototype – Ford Mar 13 '14 at 18:37

2 Answers2

8

Object.defineProperty works, but it won't be supported in older browsers. (compatibility table)

Object.defineProperty(Array.prototype, 'insert', {
  enumerable: false,
  value: function(index, element){
    this.splice(index, 0, element);
  }
});

Demonstration

p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
0

In this loop inherited properties (insert method) are not displayed.

  for (i in a){if (a.hasOwnProperty(i)) {console.log(i)}}

So, every object descended from Object inherits the hasOwnProperty method. This method can be used to determine whether an object has the specified property as a direct property of that object; unlike the in operator, this method does not check down the object's prototype chain.

This method compatible with all browsers