【发布时间】:2011-03-31 15:53:54
【问题描述】:
我正在使用 JQuery 和 jsTree,我对闭包的工作方式有些困惑。
我有一个具有 .jsTree 成员和 .populateTree 方法的对象。该方法是用一个字符串数组调用的,它应该用它来创建 jsTree 的节点。
jsTree 构建一个树形控件,其中每个节点都有一个锚点“”,其中包含该节点的文本。我想让单击文本切换节点打开或关闭,就像单击树中的 +/- 按钮一样。所以我试图添加一个 click() 函数来做到这一点,我得到了意想不到的行为。
所以,这里是代码:
populateTree: function populateTree(nodeNames)
{
if (!this.jsTree) // Note 1
return;
var me = this; // Note 2
for (var i = 0; i < nodeNames.length; i++)
{
var nodeName = nodeNames[i];
var node = this.jsTree.create_node(-1, "last", { state: 'open', data: nodeName }); //Note 3
this.jsTree.create_node(node, "last", { data: "child one" }); // Note 4
this.jsTree.create_node(node, "last", { data: "child two" });
this.jsTree.create_node(node, "last", { data: "child three" });
var anchor = node.find("a"); // Note 5
anchor.click(function() { me.jsTree.toggle_node(node); }); // Note 6
}
},
注意1:这是一个javascript对象的成员函数,所以当它被调用时,“this”指向该对象。该对象包含一个 jsTree 成员变量,该成员变量应该已经被初始化为包含一个没有节点的 jsTree 对象。
注 2:我们在注 6 中定义了一个“click”函数,当它被调用时,“this”不会指向包含 jsTree 的对象,所以我们将“this”保存在名为“me”的变量中,当“click”函数执行时,该变量将在范围内,因为创建函数创建了一个闭包,其中包括对定义函数时范围内的所有变量的引用.
注意3:对于数组中的每个元素,我们创建一个顶级节点(父节点为-1)。
注意 4:对于我们创建的每个顶级节点,我们创建三个子节点。
注意 5:每个节点都包含一个锚元素(“”),我们要附加一个“点击”函数。
注6:在“click”函数中,“me”应指向包含树的对象(见注2),“node”应指向节点我们刚刚创建的,在当前通过循环(见注3)。
我的问题?无论我点击哪个锚点,它始终是打开和关闭的最后一个顶级节点。这就像我们创建的每个“点击”函数的闭包都有一个只引用最后一个“节点”变量的闭包。这不是我认为闭包起作用的方式。
有人可以帮助我了解我的理解哪里出错了吗?
谢谢。
【问题讨论】:
-
您遇到的问题与this question 中提到的完全相同。请参阅那里接受的答案以获取解决方案
-
补充一点说明:JavaScript 语句块(“for”循环的花括号块)不创建自己的词法范围。它不同于 C++ 或 Java 等语言。只有函数会创建新范围。
标签: javascript closures