スコープとは何ですか?
ほとんどすべてのプログラミング言語の変数に格納された値であり、この値を読み込み、変更することができます。実際には、値は、可変容量に格納されたプログラム状態に付与する、の値をとります。
プログラムは、いくつかのタスクを実行することができますが、場合にはそのような概念は、ありませんが、彼らは厳しく制限され、非常に興味深いではありません。
しかし、これらの変数はどこに保存され、そしてどのように読むことを与えましたか?この目標を達成するために、いくつかのルールを開発する必要性が、このルールは次のとおりです。スコープ。
グローバルスコープ、関数スコープ、大規模な範囲でダイナミックな範囲:一般的な範囲は、いくつかのタイプに分かれています。
オブジェクト | タイプ |
グローバルウィンドウ | グローバルスコープ |
関数 | 関数スコープ(ローカルスコープ) |
{} | 大規模な範囲 |
この | ダイナミックスコープ |
変数または他の表現は、「現在のスコープ」でない場合は、使用することはできないだろう見つけることができない場合は、JavaScriptが(グローバルまたはブラウザウィンドウ)グローバルスコープまでスコープチェーンに沿っメカニズムを探し続けます。スコープ階層は、親スコープ参照変数のスコープと参照からではなく、子供の、子供が親スコープのスコープにアクセスすることができ、スコープチェーンは、一般に鎖に沿って配置することを指すように、コードに従ってもよいです
グローバルスコープ
変数またはファンクションブロック{}
定義の外側は、グローバルスコープです。ただし、関数またはコードのブロックは{}
、グローバルスコープを持つ変数で定義されていない(推奨)。
VaRの carname = " ボルボ" ; // ここでコール
carname変数
関数MyFunctionを(){ // 関数を呼び出すことができる可変} carname
コード変数は carName
グローバルスコープを有することである関数、外部で定義されています。この変数は、読み取りまたは変数が関数内で宣言されていない場合は(varキーワードを使用していない)、当然のことながら、任意の場所に変更することができ、変数はまだグローバル変数になります。
ここでcarname変数呼び出し可能な関数MyFunctionを(){carName = "ボルボ"; //ここコールcarname変数}
ブロック変数が実際に属性ウィンドウ/グローバルプレゼンス、代わりにグローバル変数のように定義されていない機能やコードの内部。言い換えれば、彼らはグローバルスコープを持っているが、それは削除することができ、およびグローバル変数はできませんが何の変数は、VARを使用して定義されていないがあります。
関数スコープ
関数定義内の変数は、ローカルスコープです。関数スコープ、外閉鎖され、外側のスコープから直接内部関数のスコープにアクセスすることはできません!
関数bar(){ VARでtestValue = ' インナー' 。 } にconsole.log(ここでtestValue)。 // 报错:にReferenceError:でtestValueが定義されていません
あなたが関数内の変数を読みたい場合は、手段を返すか閉鎖しなければなりません。
機能バー(値){ VARでtestValue = ' インナー' 。 リターンでtestValue +の値。 } にconsole.log(バー(' 楽しいです')); // "innerfun"
これは、復帰の道であり、以下は閉鎖の方法です:
機能バー(値){ あっ =試験値「内部」。 た rusult =試験値+ 値。 機能の実現(){ 戻りrusult。 }。 リターンリアライズ(); } にconsole.log(バー(' 楽しいです')); // "innerfun"
人気のある外国為替のエクスポート機能を返し、言えば、リターン関数によって返されることがあり、ルールの範囲に応じて、内部機能の関数は、関数の範囲内で得ることができる変数です。
この事実といえば、私は問題ネストされた関数のスコープ、関数は内側のネストされた関数場合は、再度と思いますか?スコープチェーン:これはに関連する別の概念です。
マップ上の注意深い観察が、あなたがプロトタイプチェーンに合わせてそれを理解するために行くことができるので、どのようなスコープチェーンを理解することは難しいことではありません。任意のスコープチェーンは、最初のグローバルスコープの第一の端部のスタックは、スタックに入れ子関係の機能に応じて、スタックにプッシュされ、そしてあります。実装の過程で、このスコープチェーン内の変数を探します。
大規模な範囲
ちょうど上記の知見と同様に、グローバルスコープに加えて、関数スコープである彼らの大規模な範囲されていない、他のプログラミング言語では、大規模な範囲は、コンセプトに精通しているが、JavaScriptに対応していません。ES6ではこの現象を変更した、大規模な範囲は、人気を博しました。ただ知って、ブロックの上に何が {}
それを。
もし(真){ せ = 1 にconsole.log() }
このコードでは、 if 后 {}
「ブロック」であり、この変数の内部は、大規模な範囲を持つことで、ルールによれば、{}
この変数の外部にアクセスできません。
ダイナミックスコープ
JavaScriptでは、多くの学生がこの時点実際には、この範囲と組み合わせ、時には明確な、時には曖昧で明確に理解しています。あなたは、このコードを見てみたいことがあります。
window.a = 3 機能テスト(){ にconsole.log(この.A) } test.bind({:2 })()// 2 試験()// 3
ここでは、バインドポイントの範囲を狭くしているが変更された { a: 2 }
、この点は、オブジェクトの現在のスコープで、それを明確に理解ではないでしょうか?
次は別の質問を熟考:スコープがすでに決定している、または内のコードの実行の過程で決定される書き込みコードにあるとき?
VaRの carname = " ボルボ" ; // ここでコールcarname変数 関数MyFunctionを(){ // 関数が可変carnameと呼ばれることもあります }
このコードを見てみましょう、carNameはVAR変数が定義されている関数のスコープと関数内のグローバルスコープである知っているコードを記述します。レキシカルスコープ:これは技術的な用語です。
スコープを定義する際に人気の変数を話す実行する際にレキシカルスコープは、静的スコープと呼ばれるように、レキシカルスコープは、静的解析によって決定することができるソースコードに依存すること、決めないと判断されます。
逆に、唯一の動的な範囲である実施段階での変数のスコープを、決めることができます。
次のコードは、それの動的スコープまたは静的スコープに従うことです考えてみましょうか?
関数foo(){ にconsole.log(A)。// 2(!不是3) } 関数bar(){ VARの A = 3 。 FOO(); } VARの A = 2 。 バー();
なぜこのようにですか?
動的スコープに基づいて分析する場合:「()fooが変数への参照を解決できないとき、それは1つのネストされたスコープに沿ってチェーンを行っておりませんが、(FOOを見つけるために、コールスタックを取ります)どこに呼び出されます。fooは()バー()のドメインになりますバー()から呼び出されるため、変数の効果を確認し、ここに3を保持する値を見つけます。
あなたは、静的スコープ解析に従った場合:fooが変数が見つからない場合、それが書かれた順序でコードを検索します実行、fooがするvar A = 2を見つけるために、外側の層で定義され、代わりのfooバーを呼び出します内部を見ています。
だから、結果は2です。
あなたは、してください助けバインドをスコープダイナミックオンにevalを、とというようにしたい場合は、この例からわかるように、デフォルトのJavaScript字句(静的)スコープを使用しています。