4

Why creating custom prototype functions like:

Array.prototype.clone = function(){
    return JSON.parse(JSON.stringify(this));
}

is making them visible when iterating over a for loop?

For example: enter image description here

It's clear that I have an array with 7 arrays inside, but for some reason it is considering all my custom functions when inside the loop. Why? How can I prevent it?

OBS: I am applying to some sort of javascript contest, which takes my algorithm and plays against other players. This loop, is inside the runner, so please consider that changing the way the iterations are processed is not an option.

This is breaking the runner as it tries to execute some code with the columns thinking that my custom function are included on it.

However, looking at their code, I noticed that it is possible to prevent this from happening as they also edit/create Array.prototype functions.

Community
  • 1
  • 1
Patrick Bard
  • 1,804
  • 18
  • 40
  • Consider using http://jsfiddle.net/ to provide the minimum code needed to reproduce the problem. – HopefullyHelpful Sep 25 '15 at 01:29
  • possible duplicate of [Javascript: hiding prototype methods in for loop?](http://stackoverflow.com/questions/1107681/javascript-hiding-prototype-methods-in-for-loop) – LJᛃ Sep 25 '15 at 01:31
  • @LJᛃ I understand the similarity, but I don't think it's a duplicate as I don't want to change the loop (as I said on the question, I can't). I want is to my custom function to be hidden even on that case. – Patrick Bard Sep 25 '15 at 01:39
  • @PatrickBard well check the second answer there, its the same as the second part of the answer you got: make your methods non enumerable. – LJᛃ Sep 25 '15 at 01:40
  • Have a read through [object.prototype](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype) methods. I could tell you which one but you would have to give me the prize. – traktor Sep 25 '15 at 03:41
  • @Traktor53 hahaha. The contest is over now, I did reach first place once, but got passed the other day. But sure, I will take a closer look to understand it better. Thank you :) – Patrick Bard Oct 28 '15 at 14:57

1 Answers1

3

Don't use for...in loops to iterate over an array. for...in loops enumerate all of the properties of an object, and since your new prototype function is enumerable, it will be listed as well. The way to avoid this is to use array.hasOwnProperty, but why do that when you can iterate over the array correctly with a regular for loop? It'll be faster and use less code:

for (var i = 0; i < this.matrix.length; i++) {
    ...
}

To make your new function not appear when enumerating an object's properties, you need to make it not enumerable:

Object.defineProperty(Array.prototype, 'clone', {
    enumerable: false,
    value: function(obj) {
        return JSON.parse(JSON.stringify(obj));
    }
});
Blender
  • 289,723
  • 53
  • 439
  • 496
  • I see, but as I said, I don't have control of the code they use. Inside **their** runner there is a `for...in` loop, and my code is breaking it. – Patrick Bard Sep 25 '15 at 01:35
  • @PatrickBard: Then either don't modify the prototype, or mark your function as not enumerable. I'd go with the former. – Blender Sep 25 '15 at 01:41