javascriptの作用領域と閉鎖を深く理解する

4268 ワード

JavaScriptを使っても何年か経ちました.ずっと機能領域と閉包に対して半解しています.最近は「あなたの知らないJavaScript」という本を拝見しました.何回も読みましたが、少し収穫ができました.
    最初にコードを見ます.
alert(age);
var age = 10;

function fn(){
    alert(age);
    var age = 20;
    alert(age)
}
fn()
alert (age)    
    簡単な言葉ですが、まず自分の予想通りの結果になったかどうかを想像してみてください.
一つは何ですか?
        まず彼のコンパイルの原理について話します.例えば、var a=10です.これは私たちがよく使う変数です.彼は声明だと思います.実はブラウザで3人のやつが彼らを処理します.
        1.エディタ:文法分析とコードの生産を担当します.
        2.エンジン:最初から最後までJavaScriptのコンパイルと実行過程を担当します.
        3.作用域:つまり、今日の主役は変数の検索と生成を収集して維持しています.それは自分の厳格なルールがあり、識別子(変数)のアクセス権限を管理しています.
        var a=10を受信しています.まずコンパイラが彼を分詞・品詞分析(Tokenizing/Lexing)して彼をvar、a、=、10、に分けます.まず、彼はスコープに変数があるかどうかを尋ねます.ない場合は、スコープ内で変数を作成します.ある場合は無視します.
        次にエディタがエンジンの運転時に依存するコードを生成します.エンジンは機能領域に行って、var aがあるかどうかを聞きます.現在のスコープのセットにaという変数がありますか?いいえ、エンジンはこの変数を使います.そうでない場合、エンジンは変数を検索し続けます.エンジンが最終的にa変数を見つけたら、10の値を与えます.さもなくばエンジンは手をあげて合図してそして投げます1つの異常!
        エンジンはどうやって調べられますか?エンジンには二つの照会方法があります. LHS RHSとは、文字通り左と右のコードです.
console.log( a );
 その中のaはRHSの引用です.ここでは割り当てられていないので、aを見たことがありますか?見つけたらconsolie.logs(...)に戻ります.そうしないと異常を投げます.コードをもう一度見てください.
age = 10;
これはLHSの引用です.彼はまずスコープについて聞きます.ageを見たことがありますか?見たことがない場合は、作成し、値を賦課します.
        はい、仕事の原理が分かりました.もう一度振り返ってみます.文章の冒頭の問題について彼の結果は次の通りです.
alert(age);//undefined
var age = 10;

function fn(){
    alert(age);//undefined
    var age = 20;
    alert(age)//20
}
fn()
alert (age)  //10
私たちの考えとは違っていますか?なぜですか?これはまた次の話題を持ち出した.
スコープアップ:JavaScriptコードは上から次へと進行すると直感的に考えられていますが、実際にはこれは完全ではなく、特殊な場合にはこの仮説が間違っているということになります.
a = 2; var a;
console.log( a );

undefined, 2;

consle.log(a) var a = 10;
のコードが から まで されていないため、 くの が10をプリントアウトすると えるかもしれません. の は があると っているかもしれません. なことに された はundefinedです.
に は ですか?それとも ですか?はずではない:
var a;
a = 10;
console.log(10)
はそうではないです. でコンパイラが2ステップの をしています. 1ステップはコンパイルで、 2 は 、すなわち です. しい は の りです.
var a ;
console.log(a);
a = 10
undefinedに ります. の の をよく します.
、グローバルスコープとは ですか? が ですか?
        JavaScriptのスコープはチェーン で び されたもので、 で に は に できます. に があります. の はバブルのように に まれています. できないものです.
function foo(a) { var b = a * 2; function bar(c) {
console.log( a, b, c ); }
bar( b * 3 ); }
foo( 2 ); // 2, 4, 12
にはfoo()とbar()の つの があります.windowグローバルオブジェクトにはfoo() つの だけが まれています.fooにはbar()も まれています. バブルはその する ブロックコードによってどこに いて されますか? たちはどうやってfoo()や の でbar()の を うかということで、 の となる の のクローズドを き しました.
、カバンを じるとは ですか?
        クローズドはずっとJavaScriptという の の つの ですが、 に です. たちが いたコードの にはクローズドがあります. くの がreturnだけが ってくるのはクローズドパックだと っているかもしれません.これは くのフォーラムであげられた です.つまり、a にb が まれています.b のスコープはまたaまたは に できます.これはクローズドです. の : が する のスコープを えてアクセスできると、 が の のスコープの で されるとしても、クローズドが します. のコードを てください.
function foo() { 
   var a = 2; 
   function bar() {
      console.log( a ); // 2
 }
bar(); 
}
foo();
これは ですか
bar()は にfoo() に まれていますので、それが な ではクローズドですが、この な ではクローズドとは えません.
じゃ、どのようにしたらクローズドになりますか?
function foo() { 
  var a = 2;
 function bar() {
   console.log( a );
  } 
  return bar; } 
var baz = foo();
baz(); //2        
bar()の はfoo()の にアクセスできる.そしてbar() を の として した.この では、barが する オブジェクト を り として う.foo()が されると、その り (すなわち のbar( )が bazに を り ててbaz()を び しますが、 には なる で の bar()を して び しました.bar()は でき、また で されるので、 は と ぶことができます.
のコードを てください.
function fnc(){
  var a = 10
  function bar(){
    console.log(a)
  }
  baz(bar)
}
function baz(fn){
  fn()
}
fnc()//10
barをbazに すと、この を び すと( はfnといいます)、fnc() のクローズドが されます.これはaにアクセスできるからです. はfnc のbar()を び し、fncを する にも を ることができます.これはクローズドとも ばれます.
どのような で を の に しても、 の された に する は、どこで されてもこの はクローズドされます.
: からの により、 にメモリに されており、ゴミ メカニズムに であり、クローズドを するとメモリ れの となります.
は なことを えました. きたいこともたくさんありましたが、 はどこから いたらいいか かりませんでした. に の が してしまいました. ノートとしてありがとうございます.