Using a prototype to create an array using methods

I want to return an array with additional methods. I usually do something like this:

MyConstructor = function(a, b, c){
    var result = [a, b, c];
    result.method1 = function(){
        return a + b + c ;
    }
    return result ;
}

var obj = MyConstructor(2, 4, 6); // removed `new`

      

But as the number of methods and uses grows, I believe it will be easier to maintain (and more efficiently) use the prototype rather than defining these new (identical) anonymous functions every time, but I can't find a way to do this without these methods ending up on Array.prototype

.

Is this possible, and if so, how?

+3


source to share


2 answers


One approach is to use a wrapper object like in Schmiddti's answer.

Or, if you don't want to use a wrapper, but want to modify the array directly, you can simply increase it:

// Define some special methods for use
var specialMethods = {
  sum: function() {
    var i = 0, len = this.length, result = 0;
    for (i; i < len; i++) result += this[i];
    return result;
  },
  average: function() {
    return this.sum() / this.length;
  }
};

function specialize(array) {
  var key;
  for (key in specialMethods) {
    if (specialMethods.hasOwnProperty(key)) {
      array[key] = specialMethods[key];
    }
  }
  return array;
}

var arr = specialize([1, 2, 3, 4, 5]);
console.log(arr.sum()); // 15
console.log(arr.average()); // 3

      

This way, you don't touch Array.prototype

and your methods are added to the array without having to redefine them over and over again. Note that they are, however, copied into each array, so there is some memory overhead - this does not do prototypical lookup.



Also, keep in mind that you can always simply define functions that operate on arrays:

function sum(array) {
  var i = 0, len = array.length, result = 0;
  for (i; i < len; i++) result += array[i];
  return result;
}

      

You don't get syntactic sugar somearray.sum()

, but the function sum

is only defined once.

It all depends on what you want / need.

+2


source


Modifying your example for use with prototype chaining would look like this:



// this could still be    var MyConstructor = function...
// but I prefer this form for Classes
function MyConstructor(a, b, c){
    this.result = [a, b, c];
}

MyConstructor.prototype.method1 = function(){
    // Array.reduce can be used for summation, or you could hardcode something like:
    // return this.result[0] + this.result[1] + this.result[2]
    // or do a summation through a for-loop, etc 
    return this.result.reduce(function(a,b){return a+b});
}

var obj = new MyConstructor(2, 4, 6);
console.log(obj.result, obj.method1()); // [2, 4, 6]  12

      

+2


source







All Articles