Reputation: 414
I have a simple function which has another function inside its for loop. The main function returns the sub function. When the main function is called, the loop runs but the sub function is not yet executed since it is not yet called. The sub function is called after the loop has been executed and hence the value of i
points to the value of the last element of the array. If I want this to have a new binding to each of the values in the array, how do I fix it?
function getName() {
const arr = ['a', 'b', 'c', 'd'];
for (let i = 0; i < arr.length; i++) {
function sendName() {
alert(arr[i]);
}
}
return sendName;
}
var receiveName = getName();
receiveName();
Upvotes: 0
Views: 117
Reputation: 16226
You might want to use an anonymous wrapper instead:
function getName() {
const arr = ['a', 'b', 'c', 'd'];
for (let i = 0; i < arr.length; i++) {
(function() {
alert(arr[i]);
})(i);
}
}
getName();
Also, as other people mentioned in comments, such implementation makes little sense until you provide more detailed explanation about why do you need it. There probably should be more elegant solutions that will fit your requirements.
Upvotes: 1
Reputation: 181
This is because its getting called only once ie... even though
function sendName(){
alert(arr[i]);
}
sendName is changing its assigned value four times but it is called only once, therefore it is only alerting "d", since d is the last value assigned. If you want to alert "a", "b", "c", "d", call the function inside the loop.
Upvotes: 0
Reputation: 993
I think there is no point to wrap alert(a[i])
in function scope as we already are using let
and it provides a block scope.
We could just use the following function and it can output the required result.
function getName() {
const arr = ['a', 'b', 'c', 'd'];
for (let i = 0; i < arr.length; i++) {
alert(arr[i]);
}
}
getName();
Upvotes: 1
Reputation: 1146
You can use array to store different functions. This example will return different letters according to N
.
function getName() {
const arr=['a','b','c','d'];
let a = [];
for(let i = 0;i<arr.length;i++) {
a.push(function () {
alert(arr[i]);
});
}
return a;
}
var receiveName=getName();
let N = 0; // returns a
receiveName[N]();
console.log(receiveName);
Hope it helps
Upvotes: 1
Reputation: 2607
You can use the bind
function to achieve what you want:
function sendName( name ) {
alert( name );
}
function getNames() {
const arr = [ 'a','b','c','d' ];
let sendNames = []; //Dunno what you want to do with this functions so let's store them in an array
for(let i = 0; i < arr.length; i++) {
sendNames.push(sendName.bind(this, arr[i])); // this - context, later arguments
}
return sendNames;
}
var receivedNames = getNames();
receivedNames[1](); //b
receivedNames[3](); //d
Upvotes: 2