JessLovely
JessLovely

Reputation: 142

Add function as method of Array native object (Is it possible to call a function as a method?)

I feel like there's probably something incredibly simple I missed in the MDN docs or something, but I've been digging for a while, and I have no clue.

Is there a way to call a function in a similar way to a method? This is basically what I'm trying to do:

function addItem(itemName, quality, quantity /*, arr*/) {
  arr.push([itemName, quality, quantity]);
}

var someArr = [['item', 1, 1]];

someArr.addItem('someOtherItem', 2, 3);
// someArr === [['item', 1, 1], ['someOtherItem', 2, 3]]

Now, mind you, I'm not trying to make a constructor or define a variable as a function. Furthermore, I am fully aware that I could simply add the array as an argument and call the function as normal. What I'm trying to accomplish is running a function in a way that, when notated as an array method, will affect that array in the specified way. How can I do this? Can I do this at all?

Upvotes: 5

Views: 248

Answers (2)

Pineda
Pineda

Reputation: 7593

DANGEROUS APPROACH (disclaimer :P):
I do not advocate extending native objects, so the following solution serves only as a reference one way to achieve it but is highly discouraged in practice. See: THE DANGERS OF EXTENDING NATIVE OBJECTS

Array.prototype.addItem = function addItem(itemName, quality, quantity) {
  this.push([itemName, quality, quantity]);
}

var someArr = [['item', 1, 1]];

someArr.addItem('someOtherItem', 2, 3);

console.log(someArr); 
// logs out: [["item", 1, 1], ["someOtherItem", 2, 3]]

The use of this inside the new method with be set to the object that the method is called upon. In the case of this example, this will be the array someArr.


A BETTER APPROACH: extend the array instance of someArr with the addItem function (and NOT the native Array object):

var someArr = [['item', 1, 1]];

// set property 'addItem' on someArr to equal named function expression
someArr.addItem = function addItem(itemName, quality, quantity) {
  this.push([itemName, quality, quantity]);
};

someArr.addItem('someOtherItem', 2, 3);

console.log(someArr); 
// logs out: [["item", 1, 1], ["someOtherItem", 2, 3]]

Upvotes: 3

Alexei Levenkov
Alexei Levenkov

Reputation: 100630

Alternatively to modifying Array prototype as shown in other answer you can add method to a particular array (or object) if that works for your case:

function addItem(itemName, quality, quantity /*, arr*/) {
  this.push([itemName, quality, quantity]);
}

var someArr = [['item', 1, 1]];
someArr.addItem = addItem;

someArr.addItem('someOtherItem', 2, 3);

var otherArray = [42];
otherArray.addItem('someOtherItem', 2, 3); // fails as otherArray does not have addItem.

Note that this will not add method to all arrays (or objects), but only to one particular array you've modified. This actually may be beneficial for cases when you add very specific method (like in this case) rather than very general once like sum or max that make sense on many types of arrays (or objects).

Upvotes: 2

Related Questions