Reputation: 466
I'm trying to learn Javascript and so I made a little code, but there is something wrong with it that I can
var array = new Array("Apple","Mangosteen","Durian","Pineapples");
...
...
function B() {
...
...
var BP = $("<p></p>");
BP.text("Click \"x\" on items to be removed").append("<br/>");
for (i=0;i<array.length;i++) {
var f = array[i];
var F = $("<div></div>");
F.attr({"class":"f"});
var N = $("<span></span>");
N.attr({"class":"n"});
N.text(f);
var d = $("<span></span>");
d.attr({"class":"cc sl"});
d.bind("click", function(e){
e.stopPropagation();
e.preventDefault();
IR(f,F);
});
d.html("×");
...
...
}
function IR(f,F) {
var a = array.indexOf(f);
array.splice(a,1);
F.remove();
}
When I added console.log(f);
in function IR()
, the value passed will always be "Pineapples", regardless if I'm clicking "x" on "Apples" or "Durian", the f
value passed will always be "Pineapples". What is wrong with it?
Upvotes: 0
Views: 123
Reputation: 111
When you declare a variable using var it will be declared within a scope of the function. That's why when you click 'x' javascript will pass to the IR function the last value of the variables - "Pineapples" and Pineapples's div. If you want to declare a variable within the 'for' cycle scope, use let. In this case, in every loop of 'for' cycle javascript will create a new variables f and F.
var array = new Array("Apple","Mangosteen","Durian","Pineapples");
function B() {
var BP = $("<div></div>");
BP.text("Click \"x\" on items to be removed").append("<br/>");
for (var i=0;i<array.length;i++) {
let f = array[i];
let F = $("<div></div>");
F.attr({"class":"f"});
var N = $("<span></span>");
N.attr({"class":"n"});
N.text(f);
var d = $("<span></span>");
d.attr({"class":"cc sl"});
d.bind("click", function(e){
e.stopPropagation();
e.preventDefault();
IR(f,F);
});
d.html("×");
F.append(N).append(d)
BP.append(F)
}
}
function IR(f,F) {
var a = array.indexOf(f);
array.splice(a,1);
F.remove();
}
Upvotes: 1
Reputation: 966
its because the scope of variable "i" is global, so var f = array[i];
will result in var f = array[3];
so you will get only "Pineapples".
I will give you a simple sample code to understand the issue. please run below code.
<script>
var funcs = [];
for (var i = 0; i < 3; i++) { // let's create 3 functions
funcs[i] = function() { // and store them in funcs
console.log("My value: " + i); // each should log its value.
};
}
for (var j = 0; j < 3; j++) {
funcs[j](); // and now let's run each one to see
}
</script>
you will get only 3 because "i" is in global scope.
Upvotes: 1
Reputation: 1550
You call a function inside a for loop - something you can read more about here JavaScript closure inside loops – simple practical example.
For now, if you're using ES6. The easiest way to solve it will be using let
in the for loop.
for (let i=0;i<array.length;i++) { ...... }
Or else, use Array.forEach()
instead of the for loop.
In your case it should be something like
array.forEach(function(fruit) {
var f = fruit;
var F = $("<div></div>");
F.attr({"class":"f"});
var N = $("<span></span>");
N.attr({"class":"n"});
N.text(c);
var d = $("<span></span>");
d.attr({"class":"cc sl"});
d.bind("click", function(e){
e.stopPropagation();
e.preventDefault();
IR(f,F);
});
d.html("×");
...
...
});
Upvotes: 2