I found such a problem when I played with cocos2d-js:

for (var i in goods_today) {
	var cur_good = goods_today[i];
	var good_label = cc.LabelTTF.create(goods_name[cur_good] + ":"
		+ prices_today[i], "Arial", 20);
	var good_item = cc.MenuItemLabel.create(good_label,
		function() {this.buyIn(cur_good);}, that);
	market_list.addChild(good_item);
}

It turned out that every MenuItemLabel got the last value of cur_good for its parameter for buyIn.

For example, in “for” loop, cur_good got value 0, 1, 2, 3, but when I click these four MenuItemLabels, they all called buyIn(3).

To explain the problem, there are two principles should be explained first.

1.Scope

{}, if(){}, for(){}

does not mean a scope in javascript, only function(){} give us a scope. e.g.

var name="global";  
if(true){  
    var name="local";  
    alert(name);
}  
alert(name);

Both alert will give us “local”, because if(){} does not make var “local” a local variable, so “global” is overwrited.

So for (var i in goods_today){} equals to var i; for (i in goods_today)

2.Scope Chain

The following codes explain how functions find variables. when b() executes, it follows the sequence of b()->a()->window, b() find name in b(), and output “Scope3” when c() executes, it follows the sequence of c()->a()->window, c() can not find name in c(), but find name in a(), and output “Scope2”

var name = "Scope1";
function a() {
	var name = "Scope2";
	function b() {
		var name = "Scope3";
		alert(name);
	}
	function c() {
		alert(name);
	}
	b();	//-->"Scope3"
	c();	//-->"Scope2"
}
a();

That explains why I got 4 “buyIn(3)”

So I need to put these codes into a function to create a scope:

for (var i in goods_today) {
	(function(that, good){
		var cur_good = goods_today[good];
		var good_label = cc.LabelTTF.create(goods_name[cur_good] + ":"
			+ prices_today[idx], "Arial", 20);
		var good_item = cc.MenuItemLabel.create(good_label,
			function() {this.buyIn(cur_good);}, that);
		market_list.addChild(good_item);
	})(this, i)
}

Now it works well~