0

I have a piece of code and particularly a function that returns an array of functions. The issue is when I call functions in this array the results is always NaN while should be a valid number. Is it probably related to the scope?

var arr = [ Math.random(), Math.random(), Math.random(), Math.random() ];
var square = function (x) { return x * x; };


function makeSquareFns(arr, square) {
var fns = [];
for (var i = 0, l = arr.length; i < l; i++) {
    fns.push(function() {
        return square(arr[i]);
    });
}
return fns;
}

var funcs = makeSquareFns(arr, square);
console.log(funcs[0]()); // IT RETURNS NaN
OliverRadini
  • 6,238
  • 1
  • 21
  • 46
VladimirCoder84
  • 175
  • 1
  • 2
  • 9
  • 2
    Change `var i` to `let i` – Patrick Roberts Sep 19 '18 at 14:42
  • @PatrickRoberts thanks it is correct, Can you explain me why? – VladimirCoder84 Sep 19 '18 at 14:45
  • 1
    `let` has lexical scope while `var` does not. Using `var`, each anonymous function (whose execution is delayed) will contain a reference to the original incremented variable `i` whose value is `arr.length` by the time `return square(arr[i]);` is executed, and `arr[arr.length]` is `undefined` and `undefined * undefined` is `NaN` – Patrick Roberts Sep 19 '18 at 14:46
  • You can use [Array.prototype.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) instead of a for loop. Example [here](https://jsfiddle.net/q14k2uv9/1/) – HMR Sep 19 '18 at 14:48
  • `var arr = [ Math.random(), Math.random(), Math.random(), Math.random() ]; var square = function (x) { return x * x; }; function makeSquareFns(arr, square) { var fns = []; arr.forEach( function(d){ fns.push(function() { return square(d); }); }) return fns; } var funcs = makeSquareFns(arr, square); console.log(funcs[0]()); // IT RETURNS NaN` – Aagam Jain Sep 19 '18 at 14:50

0 Answers0