0

I added the following functions to Array class

Array.prototype.last = function(){
     return this[this.length-1];
 }

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

And I added a library called Cosign in my Node project. I have no control over it and it do something like:

for(var k in array) alert(array[k].charAt(0))

But charAt is a String method. I believe array[k] is returning my custom function (besides the actual values, that are directory names in my case).

What is the best solution to this?

Victor Ferreira
  • 6,151
  • 13
  • 64
  • 120

2 Answers2

0

Javascript code should never iterate an array with:

for (var k in array)

because that type of iteration iterates all enumerable properties of the array object including things added as enumerable by third party libraries (shame on that library). It does not iterate just array elements. If you are using code that is doing things as bad as that, then I'd be very concerned about the quality of that code.


To iterate just array elements the code should use one of these:

for (var k = 0; k < array.length; k++)

array.forEach(fn)

Or in ES6:

for (var item of array)

If you are trying to add new methods to the Array prototype and you want them to not be picked up for a for (x in y) loop, then you need to add them as non-enumerable using Object.defineProperty() or Object.defineProperties(). When defining them this way, enumerable defaults to false and they will not get picked up the the for/in loop.

Object.defineProperties(Array.prototype, {
     last: {value: function() { return this[this.length - 1]; }},
     first: {value: function() { return this[0]; }}
});
jfriend00
  • 683,504
  • 96
  • 985
  • 979
0

So we all agree that extending native prototypes can be a bad thing, and I can proceed to an answer: by default, object property assignment (with the = sign), makes your properties enumerable: true. We can overcome this by using ES5's Object.defineProperties to specify our custom methods:

Object.defineProperties(Array.prototype, {
  last: { value: function(){ return this[this.length-1]; }},
  first: { value: function(){ return this[0]; }}
  // enumerable: false by default in Object.defineProperties
});

Now when using for in loops the methods will no longer appear. However the code in your NodeJS dependency isn't very clean for doing that in the first place.

webketje
  • 10,376
  • 3
  • 25
  • 54