可变变量可从闭包访问。如何解决这个问题? [英] Mutable variable is accessible from closure. How can I fix this?
问题描述
我通过twitter使用Typeahead。我遇到了Intellij的这个警告。这会导致每个链接的window.location.href是我的项目列表中的最后一个项目。
I am using Typeahead by twitter. I am running into this warning from Intellij. This is causing the "window.location.href" for each link to be the last item in my list of items.
如何修复我的代码?
下面是我的代码:
AutoSuggest.prototype.config = function () {
var me = this;
var comp, options;
var gotoUrl = "/{0}/{1}";
var imgurl = '<img src="/icon/{0}.gif"/>';
var target;
for (var i = 0; i < me.targets.length; i++) {
target = me.targets[i];
if ($("#" + target.inputId).length != 0) {
options = {
source: function (query, process) { // where to get the data
process(me.results);
},
// set max results to display
items: 10,
matcher: function (item) { // how to make sure the result select is correct/matching
// we check the query against the ticker then the company name
comp = me.map[item];
var symbol = comp.s.toLowerCase();
return (this.query.trim().toLowerCase() == symbol.substring(0, 1) ||
comp.c.toLowerCase().indexOf(this.query.trim().toLowerCase()) != -1);
},
highlighter: function (item) { // how to show the data
comp = me.map[item];
if (typeof comp === 'undefined') {
return "<span>No Match Found.</span>";
}
if (comp.t == 0) {
imgurl = comp.v;
} else if (comp.t == -1) {
imgurl = me.format(imgurl, "empty");
} else {
imgurl = me.format(imgurl, comp.t);
}
return "\n<span id='compVenue'>" + imgurl + "</span>" +
"\n<span id='compSymbol'><b>" + comp.s + "</b></span>" +
"\n<span id='compName'>" + comp.c + "</span>";
},
sorter: function (items) { // sort our results
if (items.length == 0) {
items.push(Object());
}
return items;
},
// the problem starts here when i start using target inside the functions
updater: function (item) { // what to do when item is selected
comp = me.map[item];
if (typeof comp === 'undefined') {
return this.query;
}
window.location.href = me.format(gotoUrl, comp.s, target.destination);
return item;
}
};
$("#" + target.inputId).typeahead(options);
// lastly, set up the functions for the buttons
$("#" + target.buttonId).click(function () {
window.location.href = me.format(gotoUrl, $("#" + target.inputId).val(), target.destination);
});
}
}
};
使用@ cdhowie的帮助,一些更多的代码:
i将更新updater和href对于点击()
With @cdhowie's help, some more code: i will update the updater and also the href for the click()
updater: (function (inner_target) { // what to do when item is selected
return function (item) {
comp = me.map[item];
if (typeof comp === 'undefined') {
return this.query;
}
window.location.href = me.format(gotoUrl, comp.s, inner_target.destination);
return item;
}}(target))};
推荐答案
您需要在这里嵌套两个函数,在创建闭包时捕获变量(而不是变量本身)的值的闭包。你可以使用参数立即调用外层函数。替换这个表达式:
You need to nest two functions here, creating a new closure that captures the value of the variable (instead of the variable itself) at the moment the closure is created. You can do this using arguments to an immediately-invoked outer function. Replace this expression:
function (item) { // what to do when item is selected
comp = me.map[item];
if (typeof comp === 'undefined') {
return this.query;
}
window.location.href = me.format(gotoUrl, comp.s, target.destination);
return item;
}
有了这个:
(function (inner_target) {
return function (item) { // what to do when item is selected
comp = me.map[item];
if (typeof comp === 'undefined') {
return this.query;
}
window.location.href = me.format(gotoUrl, comp.s, inner_target.destination);
return item;
}
}(target))
请注意,我们将 target
传递到外部函数,它变成参数 inner_target
,在调用外部函数时有效地捕获 target
的值。 outer函数返回一个内部函数,它使用 inner_target
而不是 target
和 inner_target
不会改变。
Note that we pass target
into the outer function, which becomes the argument inner_target
, effectively capturing the value of target
at the moment the outer function is called. The outer function returns an inner function, which uses inner_target
instead of target
, and inner_target
will not change.
(请注意,您可以将 inner_target
重命名为 target
并且你会没事的 - 最接近的目标
将被使用,这将是函数参数。在这么小的范围内,同样的名字可能会很混乱,所以我在我的例子中不同的命名,以便你可以看到发生了什么。)
(Note that you can rename inner_target
to target
and you will be okay -- the closest target
will be used, which would be the function parameter. However, having two variables with the same name in such a tight scope could be very confusing and so I have named them differently in my example so that you can see what's going on.)
这篇关于可变变量可从闭包访问。如何解决这个问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!