特定のケースでは違いはありません(最初のフラグメントの関数はパラメーターを使用して呼び出されますfile
が、無視するため、副作用はありません)。ただし、次の例を見てください。
var reader = new FileReader();
var my_temporary_var = 42;
reader.onload = function(e){
loadData(e.target.result, my_temporary_var);
}
これまでのところ、すべてが同じです。ただし、変更すると、無名関数内my_temporary_var
でも変更されます。これを防ぐには、クロージャを作成します。
reader.onload = (function(some_value) {
return function(e){
loadData(e.target.result, some_value);
};
})(my_temporary_var);
別の関数にバインドする引数をとる無名関数を作成し、すぐにこの関数を呼び出します。への依存my_temporary_var
が解決されていることに注意してください。
その他の例
forループで多くの関数を作成するのが好きな人もいます。
var i;
for(i = 0; i < myObjects.length; ++i)
myObjects[i].onload = function(e) { myObjects[i].doSomething(); };
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);