Js Scope and Scope Chain
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~