是的,你的理解是正确的,但为了与实现的最大兼容性,你需要在函数周围加上括号:
newInput.onchange = (function(x){
return function(){
PassFileName(x);
}
})(counter);
每当你使用函数表达式并立即调用它时,你需要使用那些括号,否则会有一个解析歧义。
更新:虽然你的方法是可以的,但值得指出的是,它有点浪费。;-) 它在每次循环迭代中创建了两个函数,外部匿名函数和内部匿名函数。这两个函数都会保留下来(除非实现优化,你知道一些引擎不会有)。相反,你可以在每个循环中只创建一个加上一个工厂函数。
// In the loop
newInput.onchange = makeHandler(x);
// Outside the loop
function makeHandler(x){
return function(){
PassFileName(x);
};
}
有些人认为这样更容易阅读(我也是),只要
makeHandler
仍然足够靠近循环,你就不会迷失方向。
使用工厂函数还可以为您提供在作用域中不关闭任何其他内容的机会,尽管那时您必须将工厂函数放得更远(例如,在一个良好包含的范围内)。
您还可以考虑使用通用的
柯里化函数,例如
Prototype提供的函数。一个不传递调用时参数的通用
curry
看起来像这样:
function curry(f) {
var args = arguments;
return function() {
f.apply(undefined, args);
};
}
但通常情况下,拥有传递运行时参数的解释器会更加有用(但更昂贵)。这是一种简单粗暴的方法(没有进行优化;通过优化可以显著降低调用时间开销):
function curry(f) {
var args = Array.prototype.slice.call(arguments, 1);
return function() {
f.apply(undefined,
args.concat(Array.prototype.slice.call(arguments)));
};
}
在这两种情况下的优点是,你没有关闭任何可以避免的新内容。
离题:此外,从技术上讲,你依赖于分号插入(在你的
return
语句的末尾应该有一个分号),我总是不建议依赖它。在这个例子中非常安全,但还是要小心。;-)