2017-07-21 13 views
2

私はクロージャを処理していましたが、通常は別の関数から返された関数としてクロージャを参照するか、別の関数内でグローバルに設定された関数であるため、新しい関数(返された関数またはグローバル変数)それが作成された最初の囲み関数内の変数への参照を持っています。最近、地図や縮小機能がクロージャを形成すると言った人がいました。これらは1つまたは複数の値を返し、何も機能しません。私はあなたが持っているすべてがコールバックであるとき、このメソッドがどのようにクロージャを形成するかを見ていません。実際、MDNは、reduce関数が "value"を返し、map関数が配列を返すと述べています。だからクロージャはどこですか?誰かがこれを説明できますか?javascriptで "reduce"と "map"がクロージャとみなされるのはなぜですか?

+1

'reduce'と' map' *自体は誰でも "閉鎖"とはみなされません。彼らが受け入れるコールバックは可能性があります。 – deceze

+2

(AIUI)関数は、(上位レベルのスコープから)字句的に表示され、独自のスコープ内で宣言されていない変数を使用する場合、実際にはクロージャとみなされます。 – Alnitak

答えて

0

ご質問ありがとうございます。これらとクロムデバッガを使用して私は結論に達しました。 Alnitakが述べているように、 "
それはその外側スコープからの変数にアクセスするならば閉鎖です。アクセスできるだけでは不十分です。"これは私が欠けていた重要なポイントです。また、クロージャーに含まれるクロムデバッガの変数のソースタブのスコープセクションにも表示されています。

routerAction: function() { 
    var name = "alex"; 
    var alex = function(v){ 
    debugger; 
    console.log("this is var ", name); 
    } 
    alex(); // if name was passed and then printed it would be local 
      // not a closure 
} 

関数はグローバルとローカルとクロージャ変数からその範囲を得る:だから、次の例を見て、私たちは何であるか閉鎖を正確に見ることができます。 alex関数に "name"をパラメータとして渡すと、ローカル変数になり、クロージャはありません。だから、もし私がそれをalexに渡し、コンソールがログに記録された "v"の名前であれば、変数はクロージャを通して参照されません。しかし、nameは関数alexの範囲外で定義されてから使用されるため、クロージャによってスコープが設定されます(これはクロムデバッガのスコープのセクションで確認できます)。この同じロジックによって、(mapまたはreduceを使用して)操作している配列が関数内に定義されている場合、配列がコールバック内で参照されている場合、コールバックはクロージャを形成する必要があります。パラメータが引数を介して渡されただけで、クロージャでアクセスされる変数はありません。これらはすべてローカル変数です。

3

関数内で定義された関数は、ローカル変数が周囲の関数に存在し、クロージャ内で使用されている場合、定義によってクロージャになります。例えば

function boil(ocean) { 
    var boiling = 100.0; 

    return ocean.map(function(h2o) { 
    return h2o.temp >= boiling ? 'vapour' : 'water'; 
    }); 
} 

ここboiling変数はメイン関数で定義され、mapに渡される関数内で使用されています。コールバック関数は、異なるコンテキストで使用されるため、クロージャの動作をより明白にしますが、同じ原則が適用されます。

1

「クロージャ」はコールバック関数です。あなたが書くとき

A closure is the combination of a function and the lexical environment within which that function was declared. 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

したがって、このような何か:MDNによると、それは存在していた範囲へのアクセスを得るため

array.map(function(object) { 
    // do something 
}); 

あなたが渡すことに機能閉鎖となりarray.mapが呼び出されたとき。それがJavaScriptの仕組みです。

+0

この構造体はクロージャ自体ではないので、それが作成された環境に依存していますか?明らかに、これを関数内で実行した場合、クロージャーを形成しますが、スタンドアロンの構文array.map ...はクロージャーの一部としてはありません。正しい?たぶん理論的な見地からは、いつも最高レベルの関数の中にいなければならないので、常に技術的にクロージャを作成します。 – trebek1

+1

これは、その外側スコープからの変数にアクセスするクロージャ_iff_です。それらにアクセスするだけでは不十分です。 – Alnitak

+0

これは、定義が少し濁ってしまうところです。私は技術的には、コールバック関数によってキャプチャされるローカル変数がない場合、それは実際には定義によるクロージャではないと思いますが、私が今までに話したことのある人は、基本的に、無名関数が別の関数呼び出しに渡されたときは、ほとんど常にクロージャになるでしょう。 –

関連する問題