分配返回匿名函数的匿名函数

Kre*_*kin 5 javascript

调用这样的东西时,JavaScript有什么区别:

var reader = new FileReader();

reader.onload = (function (theFile) {
    return function (e) {
        loadData(e.target.result); 
    };
})(file);

reader.readAsText(file);
Run Code Online (Sandbox Code Playgroud)

和(loadData函数中的结果相同):

var reader = new FileReader();

reader.onload = function(e) {
    loadData(e.target.result);
}; 

reader.readAsText(file);
Run Code Online (Sandbox Code Playgroud)

到目前为止,我已经将JavaScript用于简单的任务(输入验证,简单的ajax调用),但现在我需要一些更深层次的未完成...

Zet*_*eta 2

在您的具体情况下,没有区别(请注意,第一个片段中的函数是使用参数调用的file,但由于您忽略它,所以它不应该有任何副作用)。但是,请看下面的示例:

var reader = new FileReader();

var my_temporary_var = 42;

reader.onload = function(e){
    loadData(e.target.result, my_temporary_var);
}
Run Code Online (Sandbox Code Playgroud)

到目前为止一切都一样。但如果你改变my_temporary_var它,它也会在你的匿名函数内部改变。为了防止这种情况,你创建一个闭包:

reader.onload = (function(some_value) {
    return function(e){
        loadData(e.target.result, some_value);
    };
})(my_temporary_var);
Run Code Online (Sandbox Code Playgroud)

您创建一个匿名函数,它接受您想要绑定到另一个函数的参数,然后立即调用该函数。请注意,对的依赖性my_temporary_var已解决。

其他例子

有些人喜欢在 for 循环中创建许多函数:

var i;
for(i = 0; i < myObjects.length; ++i)
    myObjects[i].onload = function(e) { myObjects[i].doSomething(); };
Run Code Online (Sandbox Code Playgroud)

假设myObjects[0].onload将首先处理,但在for 循环之后。给定的处理程序function(e) { myObjects[i].doSomething(); };使用该对象myObjects[i]。然而,i == myObjects.length:我们访问了一个根本不存在的对象!由于我们尝试访问该函数的属性,因此我们将收到异常并且脚本将停止。

发生这种情况是因为i匿名函数中是一个引用,而不是用作值。为了防止这种情况,你必须使用闭包:

var i;
for(i = 0; i < myObjects.length; ++i)
    myObjects[i].onload = (function(index){
        return function(e) { myObjects[index].doSomething(); };
    })(i);
Run Code Online (Sandbox Code Playgroud)