1。関数範囲
1。関数範囲
これは、スコープが「関数」にあることを意味し、この関数に属するすべての変数を使用して、関数範囲全体で多重化できます。
function foo(a){var b = 2; function bar(){// ...} var c = 3;} bar(); // console.log(a、b、c)に失敗しました。 // 3つすべてが失敗しました上記の「foo」関数のいくつかの識別子が、関数の外側に配置されてアクセスすると報告されます。
2。すぐに関数式を実行します
コードスニペットの外側にラッパー関数を追加すると、内部変数と関数定義を「非表示」することができ、外部スコープはラッパー関数内の何にもアクセスできません。
たとえば、上記のバー、A、その他の識別子。これにより、変数が汚染から保護されます。
プラグインを書くときは、頻繁に機能式を実行して内部の変数を保護することがよくあります。
var a = 2;(function foo(){var a = 3; console.log(a); // 3})(); console.log(a); // 2「foo」の最初の()は関数を式に変え、2番目の()はこの関数を実行します。
特別な用語があります:Iifeは、すぐに呼び出された関数式を表します。
1。高度な使用法は、それらを関数として呼び出し、パラメーターを渡すことです
(function iife(global){var a = 3; console.log(a); // 3console.log(global.a); // 2})(window);2。目的の変化は、CMDまたはAMDプロジェクトで広く使用されているコードの実行順序を反転することです。
(function iife(factory){factory(window);})(function def(global){var a = 3; console.log(a); // 3console.log(global.a); // 2});2。ブロックスコープ
JavaScriptはブロックスコープをサポートしていません。
for(var i = 0; i <10; i ++){console.log(i);}上記のコードの「私」は次のものに相当します
var i; for(i = 0; i <10; i ++){console.log(i);}しかし、例外があり、「トライ/キャッチ」、キャッチはブロックスコープです。
{undefined(); //違法な操作を実行して例外を強制します} catch(err){console.log(err); //正常に実行できます! } console.log(err); //参照エラー:ERRが見つかりませんES6は現状を変更し、新しいLETキーワードを導入しました。これは、変数をあらゆるスコープにバインドできる(通常は{..})。言い換えれば、変数は、暗黙的にブロックスコープにあると宣言されています。
3。改善
関数範囲とブロックスコープの動作は同じであり、スコープ内で宣言されたすべての変数がこのスコープに添付されます。
1)編集と実行
変数と関数のすべての宣言は、コードが実行される前に最初に処理されます。次のコードの例を見ることができます。
a = 2; var a; console.log(a); // 2
このコードは次のとおりです。
var a; //定義宣言はコンピレーション段階a = 2; //割り当て宣言を施行され、実行段階のコンソール(a)を待つために配置されます。
2)関数の優先順位
関数が最初に宣伝され、次に変数が宣伝されます。
foo(); // 1var foo; function foo(){console.log(1);} foo = function(){console.log(2);};var foo function式は、関数foo()の宣言の前には、関数宣言が通常の変数より前に宣伝されるため、重複宣言(したがって無視されます)です。
上記のコードは次のとおりです。
function foo(){console.log(1);} foo(); // 1foo = function(){console.log(2);};4。閉鎖
閉鎖は、別の関数範囲内の変数にアクセスできる関数を指します。閉鎖を作成する最も一般的な方法は、1つの関数内で別の関数を作成することです。
別の関数を介してこの関数のローカル変数にアクセスすると、閉鎖を使用すると、アクションチェーンドメインを突破し、関数内の変数とメソッドを外側に通過できます
閉鎖機能:
1。関数は本質的にネストされています
2。内部関数は、外側のパラメーターと変数を参照できます
3.パラメーターと変数は、ごみ収集メカニズムによって収集されません
1)定義
関数が位置するスコープを覚えてアクセスできると、関数が現在のスコープの外側で実行されている場合でも、閉鎖が生成されます。
function foo(){var a = 2; function bar(){console.log(a);} return bar;} var baz = foo(); baz(); // 2 - これは閉鎖の効果です。1.関数「bar」を「baz」に割り当て、「baz」を実行します。現在の範囲は「bar」の範囲内ではありませんが、実行できます。
2。閉鎖は、ごみ収集も妨げます。 「foo」が実行されると、内部スコープが存在します。このようにして、「baz」を実行できます。
2)関数をパラメーターとして渡します
function foo(){var a = 2; function baz(){console.log(a); // 2} bar(baz);} function bar(fn){fn(); //これは閉鎖です! }内部関数bazをバーに渡し、この内部関数が呼び出されると、foo()の内部範囲の閉鎖は、アクセスできるために観察できます。
関数を最初のレベルで値タイプとして扱い、どこにでも渡すと、これらの機能に閉鎖の適用が表示されます。
タイマー、イベントリスナー、AJAXリクエスト、クロスウィンドウコミュニケーション、Webワーカー、またはその他の非同期(または同期)タスクでは、コールバック関数が使用されている限り、実際に閉鎖を使用しています!
3)ループと閉鎖
for(var i = 1; i <= 5; i ++){setimeout(function timer(){console.log(i);}、i * 1000);}印刷されるたびに6になり、遅延関数のコールバックはループの端でのみ実行されます。
スコープの仕組みによれば、現実には、ループ内の5つの機能は各反復で個別に定義されていますが、すべて共有グローバルスコープに囲まれているため、実際にはiが1つしかないということです。
ここで、閉鎖を使用して、毎回別のI印刷を実装します。
for(var i = 1; i <= 5; i ++){(function(j){settimeout(function timer(){console.log(j);}、j * 1000);})(i);}Iifeは、機能をすぐに宣言して実行することにより、スコープを作成します。 SettimeOutのコールバックは現在のスコープを覚えており、各スコープのパラメーター「J」は異なります。
上記は、編集者が紹介するJavaScriptの最も混乱する範囲、改善、および閉鎖知識の詳細な説明です。それがあなたに役立つことを願っています。ご質問がある場合は、メッセージを残してください。編集者は時間内に返信します。 wulin.comのウェブサイトへのご支援ありがとうございます!