javascriptにおけるスコープのつぶやきについて

3717 ワード

スコープは何ですか
ほとんどのプログラミング言語の基本的な機能の一つは、変数の中の値を格納し、その後にこの値をアクセスまたは修正することができることです.実際、このような変数の値を格納し、アクセスする能力こそが、プログラムに状態をもたらします.次に私達は二つの概念を紹介します.LHSクエリーとRHSクエリは私が賭け事をします.あなたは必ず「L」と「R」の意味を推測できます.それらは左側と右側を表します.左と右は何ですか?は、値付け操作の左側と右側です.言い換えれば、変数が賦値操作の左側に現れたとき、LHSクエリーが行われ、右側に現れたときにRHSクエリーが行われる.
より正確に言えば、RHSクエリーはある変数の値を簡単に検索するのと同じではないが、LHSクエリーは変数の容器自体を見つけることを試みるので、その値を割り当てることができる.この観点から、RHSは本当の意味での「割り当て操作の右側」ではなく、より正確には「非左側」である.
RHSをretrieve his source value(そのソース値を取る)と解釈できます.これは「○○の値を得る」という意味です.引き続き深く研究しましょう.下記のコードを見てください.console.log( a );ここでaにはいかなる値も与えられていないので、aに対する参照はRHS参照である.したがって、aの値を検索して取得する必要があり、このようにして、consolie.log(.)に値を伝えることができる.
比較して、例えば:a = 2;ここでaに対する参照はLHS参照であり、実際には現在の値は何かに関心がないので、この割当操作のために目標を見つけたいだけである.
LHSとRHSは、「割り当て操作の左側または右側」という意味であり、必ずしも「=割り当て操作子の左側または右側」という意味ではない.割当操作には他にもいくつかの形態がありますので、概念的には、「割り当て操作の目標は誰(LHS)か」および「誰が賦値操作の元(RHS)か」と理解したほうがいいです.
スコープは、変数(識別子)がどこでどのように検索されるかを決定するためのルールである.検索の目的が変数の割り当てである場合は、LHSクエリを使用します.変数の値を取得する目的であれば、RHSクエリーを使用します.
操作文字の割り当ては、LHSクエリを引き起こすことがあります.オペレータや関数の呼び出し時のパラメータの操作は、関連するスコープの割当動作をもたらします.
JavaScriptエンジンはまずコード実行前にコンパイルされます.この過程で、var a=2のような声明は二つの独立したステップに分解されます.
1.まず、var aはその作用領域に新しい変数を宣言する.これは最初の段階、つまりコード実行前に行われます.2.次に、a=2は変数aを照会し、値を割り当てます.
関数がどこで呼び出されても、どのように呼び出されても、その語法のスコープは関数が宣言された時の位置だけで決まります.
語法のスコープが完全にコードを書く間の関数によって宣言された位置によって定義されている場合、どうやって実行中に「修正」することができますか?
JavaScriptにはこの目的を達成するための2つの機構があります.
evalとwith
JavaScriptのeval(.)関数は文字列をパラメータとして受け入れることができ、その内容を書き込み時にプログラムに存在するようなコードとして扱うことができます.つまり、あなたが書いたコードの中でプログラムでコードを生成して実行してもいいです.コードはその位置に書いてあるようです.
eval(.)の後のコードを実行する時、エンジンは“知っています”あるいは“気になります”の前のコードは動的な形式で挿入して、そして語法の作用の領域の環境に対して修正を行います.エンジンはいつものようにワードスコープを検索します.
eval(.)の呼び出し中の「var b=3」というコードは、もともとそこにあるものとして扱われます.そのコードは新しい変数bを宣言していますので、既存のfoo(.)の動作領域を修正しました.実際には、前に述べた原理と同じように、このコードは実際にfoo(.)の内部に変数bを作成し、外部(大域)の作用領域における同名の変数を遮蔽しています.
consolone.log(.)が実行されると、foo(.)の内部にaとbが同時に見つかってしまうが、外部のbがいつまでも見つからない.そのため、通常なら出力される「1,3」ではなく「1,2」が出力されます.
JavaScriptには他の機能効果とeval(.)が似ています.set Timeout(.)とset Interval(.)の最初のパラメータは文字列であってもよく、文字列の内容は、動的に生成された関数コードとして解釈されてもよい.これらの機能は時代遅れで、提唱されていません.それらを使わないでください
プログラムでコードを動的に生成するシーンは非常にまれであり、それがもたらす利点は性能上の損失を相殺することができないからである.
結び目
語法のスコープは、コードを書く際の関数宣言の位置によって、スコープが決定されることを意味します.コンパイルされた語法分析段階では、基本的にすべての識別子がどこにあるか及びどのように声明されているかを知ることができ、実行中にどのようにそれらを検索するかを予測することができる.
JavaScriptには二つの機構があります.「騙す」という語法の作用領域:eval(.)とwith.前者は、1つまたは複数の声明を含む「コード」文字列を演算し、これにより既存の動作領域を修正することができる.後者は、本質的には、オブジェクトの参照をロールフィールドとして扱うことにより、オブジェクトの属性をロールドメインの識別子として処理し、動作時と同様に、新しいフレーズスコープを作成する.
この2つの機構の副作用はエンジンがコンパイルする時に作用領域のルックアップを最適化できないことであり、エンジンはこのような最適化が無効であると慎重にしか考えられないからである.このいずれの機構を使ってもコードの運転が遅くなります.それらを使わないでください.
関数のスコープ
var a = 2;
function foo() { // 
この技術はいくつかの問題を解決することができますが、理想的ではありません.まず、具体的な名前関数foo()を宣言しなければなりません.fooという名前自体が、役割領域を「汚染」していることを意味します.次に、この関数を関数名(foo()で明示的に呼び出してこそ、コードを実行することができる.
var a = 2;
(function foo(){ // 
関数宣言と表式を区別する最も簡単な方法は、functionのキーワードが声明の中に現れる位置を見ることである.もしfunctionが声明の中の最初の単語であるならば、関数宣言です.そうでなければ、関数表現です.
関数宣言と関数式との間の最も重要な違いは、名前識別子がどこに結び付けられますか?
(function foo(){.})は関数式としてfooは.で表される位置にしかアクセスできないことを意味します.外部作用領域はだめです.foo変数名は、自身に隠されているので、外部作用領域を不必要に汚染しないことを意味します.
var a = 2;

(function foo() { var a = 3;

 console.log( a ); // 3
      })(); 

 console.log( a ); // 2
関数はペアの括弧内に含まれているので、末尾にもう一つの()を加えることで、すぐにこの関数を実行できます.最初の()は、関数を式に変え、2番目の()はこの関数を実行します.
コミュニティはそれに専門用語を定めました.IIIIFEは即座に関数式を実行することを表します.
伝統的なIIIF形式に比べて、多くの人がもう一つの改良の形が好きです.その違いをよく観察する.最初の形式では関数式を()に含め、後に別の括弧で呼び出します.第二の形式で呼び出された括弧は、包装用の括弧に移動されます.
この2つの形態は機能的に一致している.どれを選ぶかは個人の好みによる.
はい、今日はここまでつぶやきます.端午の安康やeverbody~