Javascript変数スコープ(教育プログラム)

私にとって、Javascriptで最も問題のある場所の1つは変数管理でした。 私は簡単なロシア語で述べています。


可変スコープ


Javascriptの変数はグローバルおよびローカルです。 グローバル変数はどこでも使用でき、ローカル変数は現在のスコープ内でのみ使用できます。

技術的には、すべてのコードはそのコンテキストで実行されるため、グローバル変数はwindowオブジェクトの単なるプロパティです。

 <スクリプト>
  アラート(場所);  // window.locationに伝えます
 </ script>


その結果、 グローバル変数はwindowプロパティを上書きする可能性があります (それらが悪であり、カプセル化に違反しているという事実について私は黙っています)。

変数宣言


未定義のローカル変数に値を割り当てる場合、グローバル変数が使用または作成されます。

関数foo(){
   a = 2;
   bは3です。
   a + bを返します。
 }
アラート(a);  //未定義
 a = '非常に重要';
アラート(a);  //非常に重要
 foo();
アラート(a);  // 2


したがって、余分なものを簡単にふき取ることができます。 私の意見では、この動作は絶対に非論理的ですが、まあ、これはjavascriptで最も奇妙な場所ではありません。 いずれにせよ、 変数の暗黙的な定義は避けるべきです。

varキーワードを使用すると、変数を明示的に宣言できます。

 var a = 2;


このような行は常に新しいローカル変数を作成します。 宣言が関数の外部で発生する場合、それはグローバルであり、非常に論理的です。

関数foo(){
   var a = 2;
   var b = 3;
   a + bを返します。
 }
アラート(a);  //未定義
 var a = '非常に重要';
アラート(a);  //非常に重要
 foo();
アラート(a);  //非常に重要


関数からグローバル変数を宣言する方法は? 同じ名前のローカル変数が存在する場合、グローバル変数にアクセスする方法は? 非常にシンプル- windowプロパティとして参照する必要があります。

関数foo(){
   var location = 'location';
  アラート(場所);  // 'location'を返します
  アラート(window.location);  // window.locationを返します
   window.a = '関数からの変数';
 }
アラート(a);  //未定義
 foo();
アラート(a);  //関数からの変数


スコープの継承


Javascriptでは、関数内で関数を定義し、それをどこでも使用できるという事実に常に戸惑っていました。 まあ、はい、あなたが見ると、Rubyでも、おそらく他の多くの言語でもまったく同じことができます。

この場合、変数は非常に簡単に転送されます。関数の定義時に変数が存在していた場合、変数は関数内に存在します。 彼らが彼女を呼んだところ

関数alertOnTimeout(メッセージ、タイムアウト){
  return setTimeout(function(){ 
     //メッセージは、タイムアウトに渡された名前のない関数で利用可能になります
    アラート(メッセージ); 
   }、タイムアウト);
 }


古い方法でのコード転送eval()を通る行-この規則には該当せず、コードは定義されたスコープで実行されます。

JavaScriptのオブジェクトも関数の一種であるため、オブジェクトのプロパティは変数とまったく同じ方法で定義されます。

関数myObject(){
   var property = 0;
   //もちろん、プロパティはオブジェクト内でのみ使用可能です。
 }


また、Javascriptでは、変数のスコープは関数によってのみ制限され、 if (hello、Pascal)型のブロックによって制限されません。 したがって、関数の先頭で変数を宣言するのが最も便利です。

this


これは何? そして、この変数がオブジェクトのメソッドに自動的に表示され、以前のスコープのこの値を上書きするという事実。 解決策は簡単です-その値を別の変数に再割り当てします。

 $( 'div.with-links')。click(function(){
   var theDiv = this;  //この値を保存します
   $(this).find( 'a')。click(function(){
     alert($(this).attr( 'href'));  //これはリンクです
     theDiv.remove();  //そしてtheDivはまだ歌姫です
   });
 });


それとは別に、何らかの動作ロジックをオブジェクトにラップする場合、作成されたDOMイベントではオブジェクト自体のこの値が失われることに注意する必要があります。

関数myObject(){
   var _this = this;  //リンクを親オブジェクトに保存します
   var linkRemoved = false;

   $( 'a')。クリック(関数(){
     $(これ).remove();  //これはリンクオブジェクトです
     _this.linkRemoved = true;  // _thisは親です
   });
 }

Source: https://habr.com/ru/post/J78991/


All Articles