3

When I create a simple Visual Studio project and add JavaScript and HTML items to it, I seem to have access to all built in functions, such as indexOf(), search(), slice(), range(), etc...

However, when I try to use the sum() function (e.g. console.log(sum(range(1, 10)));) I get the following error message:

Uncaught ReferenceError: sum is not defined

Putting this message within double quotes and adding the JavaScript keyword in Google did not bring up a webpage that tells me what I am missing, hence this basic question here.

Am I missing something like a library that sum is included in? What am I doing wrong that only this particular function is not recognized?

16
  • 3
    sum is not a built in function. Hence the "undefined" error
    – Turnip
    Commented Jul 5, 2016 at 12:51
  • 2
    There is no sum() funtion in Javascript....
    – Liam
    Commented Jul 5, 2016 at 12:51
  • 2
    And there's no range either. Commented Jul 5, 2016 at 12:52
  • 3
    "here is what the program could look like if we happened to have the convenient operations range and sum available". It doesn't say that they do, though that is very confusing.
    – Liam
    Commented Jul 5, 2016 at 12:58
  • 2
    No, you need to include the math library. Do what @JaqenH'ghar has said to do
    – Liam
    Commented Jul 5, 2016 at 13:03

4 Answers 4

11

There is no built-in sum() function in Javascript.

You can create one easily with reduce():

function sum(arr) {
   return arr.reduce(function (a, b) {
      return a + b;
   }, 0);
}

var numbers = [1, 2, 3];

console.log(sum(numbers));

Or use reduce() as a oneliner:

var numbers = [1, 2, 3];

var totalSum = numbers.reduce(function (a, b) { return a + b; }, 0);

console.log(totalSum);

2

Just for the sake of it, here's a nice ES6 version:

const sum = (arr=[]) => arr.reduce((total, val) => total + val);
-1

You can create prototype functions for arrays and if you do it in some file that executes before the usage of such functions, then they will basically work. For example:

console.log(typeof [].sum);

Array.prototype.sum = function() {
    let s = 0;
    for (let i = 0; i < this.length; i++) {
        s += this[i];
    }
    return s;
}

console.log(typeof [].sum);

console.log([2, 3, 5, 7, 11, 13, 17, 19, 23, 29].sum());

The reason for me saying this is that there is no sum. So you can create a range function that creates an array for you and call sum() on the resulting array.

    function range(start, end) {
        let output = [];
        while (start <= end) {
            output.push(start++);
        }
        return output
    }

    Array.prototype.sum = function() {
        let s = 0;
        for (let i = 0; i < this.length; i++) {
            s += this[i];
        }
        return s;
    }

console.log(range(1, 10).sum())

5
  • 1
    Yes it's possible, but see: Why is extending native objects a bad practice?
    – Peter B
    Commented Apr 9 at 20:51
  • @PeterB thanks for the link, however, I'm not convinced that having a sum availability for arrays is risky at all. What is the exact worry? Can you describe an actual scenario when having a sum for Javascript is a problem? The only case I can imagine is when a library also defines a sum for it. But then I would expect the other sum to behave like the one I created. Commented Apr 9 at 23:18
  • For an isolated case there is absolutely no worry. But as soon as you start using code that isn't yours (jQuery, underscore.js, a polyfill script) there is the risk that your code may break theirs, or their code may break yours. For that reason a 'bad practice' warning is justified, to make people aware of the risks.
    – Peter B
    Commented Apr 10 at 8:30
  • @PeterB I simply don't see the big risk involved. Let's suppose that I create f1, f2, ... fn as new prototype functions and let's suppose further that I have some files where these functions are being used with the assumption that they are my functions. The worry you expressed is that I may include some libraries which define prototype functions with the same name. Let's assume that this is possible. The solution is to have unit tests that check whether the function still works as intended after the library load. To be quite honest, the accepted solution defines a function, Commented Apr 10 at 9:16
  • @PeterB which is global and to me it seems way more probable that a library will have a function sum than the same library having a prototype function. However, I still upvoted the answer. Sure, we can create classes like the article you have sent suggests, but I do see a great benefit of being able to compute .sum() for arrays without referring to separate classes and if a library overrides it, then solving the issue does not seem to be too hard (search for all references of .sum() in our custom code and replace it with something else), so I'm simply unconvinced about this being a serious Commented Apr 10 at 9:20
-2

I think there is the potential to clean up the previous answers even further, take a look:

const sum = arr.reduce((accumulator, currentValue) => accumulator + currentValue);

The arrow function simplifies the function declaration syntax plus there is no need to declare initialValue since we want to just get the sum of the elements from the array of numbers.

1
  • There definitely is a point to passing 0 as the initial value: it handles empty arrays properly. Commented Apr 10 at 4:06