0

Since I had to remove some elements from my arrays, I followed a few pieces of code found in stackoverflow and came up with this one:

Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

For some reasons, however, this piece of code is being printed EVERYWHERE whenever something has something to with an array.

Example:

this piece of code:

Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

Scadenza.prototype.init = function() {
    this.promemoria = (this.promemoria == "")?("NO"):(this.promemoria);
    var gruppo = this.group; // convert array to string.
    this.group = "";
    for (var i in gruppo) {
        if (i != (gruppo.length - 1)) {
            this.group += gruppo[i] + ", ";
        }
        else {
            this.group += gruppo[i];
        }
    }
    alert(this.group);
};

This piece of code is supposed to convert the array this.group (stored temporarily in the variable "gruppo") into a string (that's quite obvious, I think).

It is, of course, doing it's job greatly, if it wouldn't be that its alert is:

[DATA NEEDED]function (from, to) { var rest = this.slice((to || from) + 1 || this.length); this.length = from < 0 ? this.length + from : from; return this.push.apply(this, rest); }

This piece of code is being also sent to a database through an AJAX request and the result of the query, at the desired coloumn, is this one:

function (from, to) { var rest = this.slice((to || from) + 1 || this.length); this.length = from < 0 ? this.length + from : from; return this.push.apply(this, rest); },

I'm quite surprised this is happening but I have ABSOLUTELY no idea on how to fix it.

No errors have been alerted while loading the page or when clicking the button that throws this event.

Any idea?

ps: Not sure if helps, but I'm using jQuery.

@comments:

The normal for loop actually doesn't fix this:

Scadenza.prototype.init = function() {
    this.promemoria = (this.promemoria == "")?("NO"):(this.promemoria);
    var gruppo = this.group; // convert array to string.
    this.group = "";
    for (var i = 0; i < gruppo.length; i++) {
        if (i != (gruppo.length - 1)) {
            this.group += gruppo[i] + ", ";
        }
        else {
            this.group += gruppo[i];
        }
    }
    alert(this.group);
};

Alert is still the same.

briosheje
  • 7,356
  • 2
  • 32
  • 54
  • possible duplicate of [Why is using "for...in" with array iteration such a bad idea?](http://stackoverflow.com/questions/500504/why-is-using-for-in-with-array-iteration-such-a-bad-idea) – Bergi Sep 18 '13 at 17:18
  • It doesn't work either with a normal for loop, thanks. – briosheje Sep 18 '13 at 17:20
  • It does. Maybe you didn't fix all occurrences of `for in` loops… What does `this.group` contain? Maybe the `.toString()` methods of the items do it wrong as well. – Bergi Sep 18 '13 at 17:24
  • It's better to use console.log instead of alert to debug your code. In chrome press F12 to open the developer tools and the console. In Firefox press control+shift + k. Then you can add information to your log like `console.log("in for i – HMR Sep 19 '13 at 01:37

2 Answers2

4

Use proper for (var i=0; i<arr.length; i++) loops for iterating arrays. for in enumerations will enumerate prototype properties as well, do not use them on arrays. You are doing that in your init method for example.

Btw, for that task you want to use .join anyway:

Scadenza.prototype.init = function() {
    if (this.promemoria == "")
        this.promemoria = "NO";
    this.group = this.group.join(", "); // convert array to string
    alert(this.group);
};
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • After removing array.prototype.remove and using .join it fixed it, thanks! Any idea, however, why this was happening even with normal for loops? – briosheje Sep 18 '13 at 17:25
  • I didn't say to remove `Array.prototype.remove`. It does not happen with normal loops. Either you had some caching issue with the code, or you overlooked an occurrence of `for in` (maybe in the `this.group[i].toString` methods?). Please provide a self-contained example that exhibits this behaviour if you still are suffering from the issue. – Bergi Sep 18 '13 at 17:28
  • For some reason this fixed it, no more random functions parsed anymore, but I surely won't use (for variable in array) anymore with arrays, thanks! Is it suitable for objects, anyway? – briosheje Sep 18 '13 at 17:30
  • Yes, it is OK for plain objects. `Object.prototype` will never contain enumerable properties. – Bergi Sep 18 '13 at 17:31
  • @Bergi There is a rare case when you set only a couple of elements in the array that are far apart: `arr[0]=1;arr[1000]=2` you should use for in with hasOwnProperty `for(key in arr){if(arr.hasOwnProperty(key){...do stuff here` – HMR Sep 19 '13 at 01:30
3

When you change the Array prototype, the method is added to the Array object as a new attribute. When you iterate with for (var attr in object) you are iterating over the object and all of its attributes. Therefore, your new method is included in that loop.

You need to use a for (var i=0; i<a.length; i++) loop. That will only include items in the array.

Eric H.
  • 6,894
  • 8
  • 43
  • 62
  • As already posted above, this doesn't fix it! I'm still getting the same alert... – briosheje Sep 18 '13 at 17:22
  • can you show us how you are assigning this.group before it is assigned to `gruppo` in your `init` method? – Eric H. Sep 18 '13 at 17:25
  • I've fixed it using the .join, anyway, this.group was assigned by taking values from checkboxes, pushing them into an array. Maybe there is something wrong there, but using .join fixed it! – briosheje Sep 18 '13 at 17:27