21

I often found myself wanting to do certain operations for all the items in an array and I wished that JavaScript had something like C#'s LINQ. So, to that end, I whipped up some extensions of the Array prototype:

var data = [1, 2, 3];
Array.prototype.sum = function () {
    var total = 0;
    for (var i = 0; i < this.length; i++) {
        total += this[i];
    }
    return total;
};
Array.prototype.first = function () {
    return this[0];
};
Array.prototype.last = function () {
    return this[this.length - 1];
};
Array.prototype.average = function () {
    return this.sum() / this.length;
};
Array.prototype.range = function () {
    var self = this.sort();
    return {
        min: self[0],
        max: self[this.length-1]
    }
};
console.log(data.sum()) <-- 6

This makes working with arrays much easier if you need to do some mathematical processing on them. Are there any words of advice against using a pattern like this? I suppose I should probably make my own type that inherits from Array's prototype, but other than that, if these arrays will only have numbers in them is this an OK idea?

wootscootinboogie
  • 8,461
  • 33
  • 112
  • 197

1 Answers1

6

Generally speaking you should avoid extending base objects because it may clash with other extensions of that object. Ideally extending Array and then modifying THAT is the safest way to do things as it is guaranteed to not clash with other developers who might try to do the same thing (even though they shouldn't).

Basically, avoid extending base objects when possible because it can get you into trouble for very little real benefit compared to extending the array object.

Community
  • 1
  • 1
moberemk
  • 1,597
  • 1
  • 18
  • 39
  • 4
    _"extending Array and then modifying THAT"_ While your answer isn't bad, that isn't as easy as you make it out to be, unless I'm missing something... ;) – Qantas 94 Heavy Feb 21 '14 at 23:58
  • 1
    Oh it's definitely not THAT easy don't get me wrong, but it IS doable; a well-explained example can be seen at http://www.bennadel.com/blog/2292-Extending-JavaScript-Arrays-While-Keeping-Native-Bracket-Notation-Functionality.htm – moberemk Feb 22 '14 at 03:08
  • The issue with that is that it isn't a real array -- it just has all the prototype methods. For example, the `length` property doesn't update like a real array, unless you use the `add` method that's provided. – Qantas 94 Heavy Feb 22 '14 at 03:11
  • 5
    That seems like a very complicated way of extending the array object. I would just use a factory like `arrayExt = function(array = []){array.method = () => 'method'; return array}` – CervEd Oct 17 '16 at 00:19
  • @CervEd: This is rather terse. Could you point to an example? – raarts Jun 27 '17 at 08:03
  • @raarts not 100% sure what you mean.. `arrayExt` is a function that returns an extended array object – CervEd Jul 11 '17 at 21:19
  • 2
    Why not? It's common nowadays to extend from the base object. It's indeed a warning (not generally a big NO situation). I do agree that it may clash with other extensions of that object. The developer of the custom extension is the one responsible to ensure that it won't get any conflict with any other extensions. as long as it serves your purpose & requirement, why not? – Radityo Ardi Jan 22 '21 at 11:53
  • @RadityoArdi Even if you have a developer that's been very careful to only extend a base object using custom methods it uses internally (say something like `array._veryCustomMethod`, that's still risky--for example, you can have two versions of the same library imported as dependencies at different points that will end up modifying the same prototype. You can't ever change your implementation of `array._veryCustomMethod` without potentially breaking your own code in subtle ways. – moberemk Jan 29 '21 at 17:38
  • 2
    Sir, that's like ranting to anyone cutting pasta when eating, too strict. But you have all rights in your opinion to avoid extending the base Javascript object & I respect that. Look around, we've got many Javascript frameworks around (jQuery, Angular), and transpiler (CoffeeScript, TypeScript), which is essentially extending something from the base object. Who knows someone in the future might create another Javascript framework with $ sign, and it might get conflict too with jQuery? Javascript was created to be flexible like Python does. – Radityo Ardi Feb 01 '21 at 05:33
  • @RadityoArdi actually, your example of other frameworks is wrong. Any SOLID framework, like jQuery, Angular, Vue, React etc do NOT modify native prototypes. Instead, they create their own abstraction, encapsulated within their own global namespace. Hell, even lodash, which is comprised entirely of array and object manipulations does so within it's _ namespace. The creator of this answer is absolutely correct. You should NEVER modify native javascript prototypes, for the stated reason. There's simply no valid reason to. Instead, use a factory function or your own namespace. – Hybrid web dev Jun 02 '21 at 23:10
  • 1
    This wrong-right thing is debatable & very gray, can go until the sun supernova explosion happen. My point is, even the creator of jQuery can't guarantee that the $ sign is for themselves, it can be used for any other libraries too. https://api.jquery.com/jquery.noconflict/ @wootscootinboogie just asking if he can extend the array prototype function since it's not being used. There's simply IS a valid reason to do so, to help the programmer do sum, first, last, average, and all those stuff that doesn't exist in the natural array prototype. So, if it makes people easier to code, why not? – Radityo Ardi Jul 13 '21 at 09:15
  • 1
    This shouldn't be accepted the answer. Clearly it doesn't respond the to nuclear question. How to extend. – Luís Assunção Sep 10 '21 at 19:42