我正在尝试使用以下代码以编程方式向 Photoshop 插件添加一个偶数侦听器:
actionObject = [];
actionObject[0] = {name: "A1", id: "95ce"};
actionObject[1] = {name: "B2", id: "9dk2"};
.
.
actionObject[10] = {name: "H6", id: "9334"};
for (i = 0; i < actionObject.length; i++ ){
console.log("#btn" + actionObject[i].name);
var action = actionObject[i];
$("#btn" + action.name).click(async function () {
await ExecuteAsModal(() => runAction(action));
});
}
我面临的问题是,当触发此事件时,无论我按下哪个按钮,它总是尝试使用 actionObject 数组中的最后一个“action”运行“runAction”。 在这种情况下,它总是尝试使用
运行它action={name: "H6", id: "9334"}
如何确保每个按钮都以正确的“操作”运行“actionObject”?
您遇到的问题是一个经典的闭包问题。在循环中,当您使用
$("#btn" + action.name).click(...)
定义单击事件处理程序时,action
变量是通过引用捕获的,而不是通过值捕获的。因此,当单击事件发生时,循环已经完成,并且 action
保存循环中分配给它的最后一个值。
为了解决这个问题,您需要为循环的每次迭代创建一个新的作用域,以便每个事件处理程序捕获
action
的正确值。
例如,您可以使用 IIFE 来完成此操作,如下所示:
for (var i = 0; i < actionObject.length; i++) {
(function(action) {
$("#btn" + action.name).click(async function () {
await ExecuteAsModal(() => runAction(action));
});
})(actionObject[i]);
}
可能更好的方法是使用箭头函数,所以它看起来像这样:
for (let i = 0; i < actionObject.length; i++) {
let action = actionObject[i];
$(`#btn${action.name}`).click(async () => {
await ExecuteAsModal(() => runAction(action));
});
}