Search code examples
javascriptarraysw2ui

Array.prototype causing error


Am trying to implement w2ui multi select in one of d3 charts which am working on.

This is the link to sample jsfiddle with the problem.

I have three function :

//get a column of an array
Array.prototype.getColumn = function(name) {
  return this.map(function(el) {
    // gets corresponding 'column'
    if (el.hasOwnProperty(name)) return el[name];
    // removes undefined values
  }).filter(function(el) {
    return typeof el != 'undefined';
  });
};
//remove duplicates in an array
Array.prototype.contains = function(v) {
  for (var i = 0; i < this.length; i++) {
    if (this[i] === v) return true;
  }
  return false;
};
Array.prototype.unique = function() {
  var arr = [];
  for (var i = 0; i < this.length; i++) {
    if (!arr.contains(this[i])) {
      arr.push(this[i]);
    }
  }
  return arr;
}

I need to implement these three in one of my functions.

Problem is that, whenever I try to implement these functions with Array.prototype I get items in the multiselect as "undefined". The number of "undefined" is directly propotional to the number of functons with Array.prototype functions.

If I remove these functions, I can get the multi-select to work properly(only the multi-select part, not the chart as a whole. I don't understand, what's causing the error.

Any help is appreciated. Thanks.


Solution

  • In general messing with the core javascript objects is a bad idea when you are working with the third party libraries. If you still want to keep it this way and solve this particular problem use the Object.defineProperty method, turning off the enumerable bit

    So for example change

    Array.prototype.contains = function(v) {
      for (var i = 0; i < this.length; i++) {
        if (this[i] === v) return true;
      }
      return false;
    };
    

    to

    Object.defineProperty(Array.prototype, 'contains', {
        enumerable: false,
        value: function(v) {
            for (var i = 0; i < this.length; i++) {
                if (this[i] === v) return true;
            }
            return false;
        }
    });
    

    and similar for other prototype method that you have added.