wat*_*ata 6 javascript closures onchange
我最近进入了闭包和匿名函数,我想知道我的代码是否是正确的方法(它有效!):
newInput.onchange = function(x){
return function(){
PassFileName(x);
}
}(counter);
Run Code Online (Sandbox Code Playgroud)
所以这是一个"保存"当前"计数器"值(1,2,3 ...)的循环.如果我没有返回函数,那么'counter'将始终是'counter'的最后一个值.
我是否正确使用该代码?或者有更好的方法来"捕获"当前的计数器并将其附加到onchange事件?
谢谢!
是的,您正确地接近它,但为了最大程度地兼容实现,您需要在函数周围加上括号:
newInput.onchange = (function(x){
// ^--- here
return function(){
PassFileName(x);
}
})(counter);
// ^--- and here
Run Code Online (Sandbox Code Playgroud)
每当你做一个函数表达式并立即调用它时,你需要那些parens,因为否则会有解析歧义.
更新:
虽然你的方法很好,但值得指出的是它有点挥霍.;-)它在循环的每次迭代中创建两个函数,外部匿名函数和内部匿名函数.这两个功能都存在(除非实现优化,你知道一些引擎不会有).相反,你可以只有一个循环加上一个工厂函数:
// In the loop
newInput.onchange = makeHandler(x);
// Outside the loop
function makeHandler(x){
return function(){
PassFileName(x);
};
}
Run Code Online (Sandbox Code Playgroud)
有些人可能会认为它更容易阅读(我当然这样做),前提是makeHandler它仍然足够接近你不会失去轨道的循环.
使用工厂功能还为您提供了不关闭范围内任何其他功能的机会,尽管您必须将工厂功能放得更远(例如,在一个包含良好的范围内).
您可能还会考虑一般的咖喱功能,例如Prototype提供的功能.一个通用curry的是不上呼叫时间传递参数如下:
function curry(f) {
var args = arguments;
return function() {
f.apply(undefined, args);
};
}
Run Code Online (Sandbox Code Playgroud)
但它通常是更有帮助的(但更昂贵)有一个确实的运行参数传递也是如此.这是一个廉价和肮脏的(未优化;优化调用时间开销可以显着减少):
function curry(f) {
var args = Array.prototype.slice.call(arguments, 1);
return function() {
f.apply(undefined,
args.concat(Array.prototype.slice.call(arguments)));
};
}
Run Code Online (Sandbox Code Playgroud)
两种情况下的优势在于,您不会关闭任何可以避免的新事物.
偏离主题:另外,从技术上讲,你依赖于分号插入的恐怖(在你的return陈述结尾应该有一个分号),我一直主张不依赖分号.但是,在这个例子中,相当安全.;-)
| 归档时间: |
|
| 查看次数: |
7636 次 |
| 最近记录: |