我正在尝试为foobar2000音乐播放器在WSH组件上构建一个jscript接口 在某些时候,我需要创建一个可变数量的按钮,每个按钮调用相同的函数,但使用不同的参数。我可以使用 for loop 和 array 创建按钮。但是,所有按钮都只会传递最后一个按钮的参数。
以下是我用来添加按钮的代码:
for (var i=0; i<_groupsArray.length; i++) {
_btn = _groupsArray[i];
ƒview.addButton(_btn, _img, function () {setView(_btn)}, function () {doPlay(_btn)});
}
在这种情况下,当我点击按钮时,_btn既被用作按钮标签又想要传递给函数的参数(它将是艺术家名称或专辑标题或类似内容)。 ƒview是一个包含按钮的自定义对象。我创建它所以我不必指定按钮的位置,ƒview会在需要时计算它们。
这是实际创建按钮的addButton方法的一部分(其余部分确实计算布局)。每个action参数都作为参数传递给正在创建的按钮,而不需要addButton方法进行任何处理。
this.addButton = function(label, img, action1, action2, action3, action4, action5) {
...
new ButtonObject(label, __x, __y, __w, __h, action1, action2, action3, action4, action5);
最后,我在我的buttonObject构造函数中有这个:
function ButtonObject(label, x, y, w, h, action1, action2, action3, action4, action5) {
...
this.action1 = action1;
this.action2 = action2;
this.action3 = action3;
this.action4 = action4;
this.action5 = action5;
...
this.act1 = function () {
var __doIt = function () {this.action1();};
return __doIt;
}
在 for循环期间传递的函数最终将作为action1,action2 ...属性存储在对象中。
我尝试了许多使用act1方法调用 action1 的方法,包括直接调用 this.action1();使用 this.action1.apply();试图形成一个如上所述的clausure。它会调用正确的操作,但使用创建的 last 按钮的参数,否则它将崩溃或无效。
我现在没有想法尝试。我分别成功地传递了函数和参数,但这是一个丑陋的技巧。我已经阅读了一些关于clausures的教程,以及它们如何保持局部变量的活着,但在这种情况下我仍然无法让它们为我工作。当我单击“此对象不处理此属性或方法”指向该行的按钮时,我的最后一次尝试(正如您在代码中看到的那样)将崩溃
var __doIt = function () {this.action1();};
那么如何在每个按钮中保持“活着”的参数呢?
答案 0 :(得分:1)
尝试类似:
for (var i=0; i<_groupsArray.length; i++) {
_btn = _groupsArray[i];
ƒview.addButton(_btn, _img,
function(b) {return function () {setView(b)};}(_btn),
function(b) {return function () {doPlay(b)};}(_btn)
);
}
您需要创建一个闭包来保存_btn的值,而不仅仅是绑定它。额外的包装函数就是这样做的。