役割ドメインとは?いくつかの一般的な役割ドメインの詳細
4248 ワード
ほとんどのプログラミング言語は、変数に値を格納し、この値を読み取り、変更できます.実際,変数に値を格納し,値を取り出す能力は,プログラムに状態を与えている.
このような概念がなければ、1つのプログラムはいくつかのタスクを実行することができますが、それらは極めて制限され、非常に面白くありません.
しかし、これらの変数はどこに格納され、どのように読み込まれますか?この目標を達成するためには、役割ドメインというルールを制定する必要があります.
一般的な役割ドメインは主にいくつかのタイプに分けられます:グローバル役割ドメイン、関数役割ドメイン、ブロック状役割ドメイン、動的役割ドメイン.
オブジェクト
を選択します.
global/window
グローバル役割ドメイン
function
かんすうさぎょういき
{}
ブロックさようりょういき
this
ダイナミックドメイン
変数または他の式が「現在の役割ドメイン」にない場合、JavaScriptメカニズムは、グローバル役割ドメイン(globalまたはブラウザのwindow)が見つからない場合に使用できないまで、役割ドメインチェーンに沿って検索し続けます.役割ドメインはコード階層に基づいて階層化することもでき、サブ役割ドメインが親役割ドメインにアクセスできるようにします.通常は、チェーン式の役割ドメインチェーンに沿って検索され、親役割ドメインからサブ役割ドメインの変数と参照を参照できません.グローバル役割ドメイン 変数は、関数またはコードブロック{}の外で定義され、グローバル役割ドメインです.ただし、関数やコードブロック{}内で定義されていない変数もグローバル役割ドメインを持つ(推奨しない).
上記のコードの変数carNameは、グローバルな役割ドメインを持つ関数外で定義されています.この変数は任意の場所で読み込まれたり修正されたりすることができます.もちろん、変数が関数内で宣言されていない場合(varキーワードを使用していない場合)、変数は依然としてグローバル変数です.
上記の例ではcarNameは関数内にありますが、グローバルな役割ドメインがあり、globalまたはwindowのプロパティとして存在します.
関数内部やコードブロックに定義されていない変数は、グローバル変数ではなくwindow/globalの属性として存在します.すなわちvarを使用して定義されていない変数はグローバル役割ドメインを有するがdeleteされ得るが、グローバル変数はできない.関数役割ドメイン 関数内部で定義される変数は、ローカル役割ドメインです.関数の役割ドメイン内は、外部には閉鎖されており、外部の役割ドメインから関数内部の役割ドメインに直接アクセスできません.
関数内の変数を読み込むにはreturnまたは閉パッケージを使用する必要があります.
これはreturnを借りた方法で、以下はパッケージを閉じる方法です.
一般的には、returnは関数の対外交流の出口であり、returnは関数を返すことができ、作用ドメインの規則に基づいて、関数内部のサブ関数は関数の作用ドメイン内の変数を取得することができる.
これといえばネスト関数の役割ドメインの問題を思い浮かべますが、inner関数がさらにネスト関数になったら?これはもう一つの概念に関連している:役割ドメインチェーン.
上図をよく見ると、役割ドメインチェーンが何なのか理解するのは難しくありません.プロトタイプチェーンのように理解できるからです.いずれの役割ドメインチェーンもスタックであり、まずグローバル役割ドメインをスタックの底に押し込み、関数のネスト関係に従ってスタックに一度押し込む.実行時にこの役割ドメインチェーンに従って変数を探します.ブロック作用域 他のプログラミング言語ではブロック役割ドメインはよく知られている概念ですが、JavaScriptではサポートされておらず、上記の知識のようにグローバル役割ドメインを除いて関数役割ドメインであり、自分のブロック役割ドメインはずっとありません.ES 6ではこの現象が変化し,ブロック作用域が普及している.何がブロックなのかについては、認識さえすれば
このコードではif後{}が「ブロック」であり,この中の変数はこのブロック状の役割ドメインを持ち,ルールに従って{}以外はこの変数にアクセスできない.ES 6のlet.ダイナミックドメイン JavaScriptでは多くの学生がthisの指向をはっきりしたりぼやけたりしていますが、実際には役割ドメインを結合するとthisに対してはっきりした理解があります.まず、このコードを見てみましょう.
ここでbindはすでに役割ドメインの範囲を修正して{a:2}を指していますが、thisは現在の役割ドメインオブジェクトを指しているので、はっきり理解できますか?
次にもう一つの問題を考えてみましょう.役割ドメインはコードの作成時に決定されたのでしょうか.それともコードの実行過程で決定されたのでしょうか.
このコードを見て、コードを書くときにcarNameがグローバル役割ドメインであり、関数内部のvarで定義された変数が関数役割ドメインであることがわかります.これは専門用語です.文法の役割ドメインです.
一般的に変数の役割ドメインは定義時に決定され、実行時に決定されるのではなく、すなわち文法の役割ドメインはソースコードに依存し、静的解析によって決定されるため、文法の役割ドメインは静的役割ドメインとも呼ばれる.
逆に,変数の役割ドメインは実行段階でしか決定できない,すなわち動的役割ドメインである.
次のコードは動的役割ドメインに従っているのか、それとも静的役割ドメインに従っているのかを見てみましょう.
どうしてこんなことになったの?
動的役割ドメイン解析に従うと、foo()がaの変数参照を解析できない場合、ネストされた役割ドメインチェーンに沿って1つ上へ行くのではなく、呼び出しスタックに沿って上へ行ってfoo()がどこから呼び出されたかを見つけることができます.foo()はbar()から呼び出されるため、bar()の役割ドメインで変数をチェックし、ここで値3を持つaを見つけます.
静的役割ドメイン解析:fooが実行されたときにaという変数が見つからなかった場合、コードの書く順序で上を探します.つまりfoo定義の外層は、foo呼び出しのbar内ではなくvar a=2を見つけます.
だから結果は2です.
この例からJavaScriptのデフォルトでは、動的な役割ドメインを開くにはbind、with、evalなどを使用します.
このような概念がなければ、1つのプログラムはいくつかのタスクを実行することができますが、それらは極めて制限され、非常に面白くありません.
しかし、これらの変数はどこに格納され、どのように読み込まれますか?この目標を達成するためには、役割ドメインというルールを制定する必要があります.
一般的な役割ドメインは主にいくつかのタイプに分けられます:グローバル役割ドメイン、関数役割ドメイン、ブロック状役割ドメイン、動的役割ドメイン.
オブジェクト
を選択します.
global/window
グローバル役割ドメイン
function
かんすうさぎょういき
{}
ブロックさようりょういき
this
ダイナミックドメイン
変数または他の式が「現在の役割ドメイン」にない場合、JavaScriptメカニズムは、グローバル役割ドメイン(globalまたはブラウザのwindow)が見つからない場合に使用できないまで、役割ドメインチェーンに沿って検索し続けます.役割ドメインはコード階層に基づいて階層化することもでき、サブ役割ドメインが親役割ドメインにアクセスできるようにします.通常は、チェーン式の役割ドメインチェーンに沿って検索され、親役割ドメインからサブ役割ドメインの変数と参照を参照できません.
var carName = "Volvo";
// carName
function myFunction(){
// carName
}
上記のコードの変数carNameは、グローバルな役割ドメインを持つ関数外で定義されています.この変数は任意の場所で読み込まれたり修正されたりすることができます.もちろん、変数が関数内で宣言されていない場合(varキーワードを使用していない場合)、変数は依然としてグローバル変数です.
// carName
function myFunction(){
carName = "Volvo";
// carName
}
上記の例ではcarNameは関数内にありますが、グローバルな役割ドメインがあり、globalまたはwindowのプロパティとして存在します.
関数内部やコードブロックに定義されていない変数は、グローバル変数ではなくwindow/globalの属性として存在します.すなわちvarを使用して定義されていない変数はグローバル役割ドメインを有するがdeleteされ得るが、グローバル変数はできない.
function bar(){
var testValue = 'inner';
}
console.log(testValue) // :ReferenceError:testValue is not defined
関数内の変数を読み込むにはreturnまたは閉パッケージを使用する必要があります.
function bar(value){
var testValue = 'inner';
return testValue+value;
}
console.log(bar('fun')) //"innerfun"
これはreturnを借りた方法で、以下はパッケージを閉じる方法です.
function bar(value){
var testValue = 'inner';
var result = testValue+value;
function innser(){
return result
};
return innser();
}
console.log(bar('fun')) //"innerfun"
一般的には、returnは関数の対外交流の出口であり、returnは関数を返すことができ、作用ドメインの規則に基づいて、関数内部のサブ関数は関数の作用ドメイン内の変数を取得することができる.
これといえばネスト関数の役割ドメインの問題を思い浮かべますが、inner関数がさらにネスト関数になったら?これはもう一つの概念に関連している:役割ドメインチェーン.
上図をよく見ると、役割ドメインチェーンが何なのか理解するのは難しくありません.プロトタイプチェーンのように理解できるからです.いずれの役割ドメインチェーンもスタックであり、まずグローバル役割ドメインをスタックの底に押し込み、関数のネスト関係に従ってスタックに一度押し込む.実行時にこの役割ドメインチェーンに従って変数を探します.
if(true){
let a = 1
console.log(a)
}
このコードではif後{}が「ブロック」であり,この中の変数はこのブロック状の役割ドメインを持ち,ルールに従って{}以外はこの変数にアクセスできない.ES 6のlet.
window.a = 3
function test () {
console.log(this.a)
}
test.bind({ a : 2 })() //2
test() //3
ここでbindはすでに役割ドメインの範囲を修正して{a:2}を指していますが、thisは現在の役割ドメインオブジェクトを指しているので、はっきり理解できますか?
次にもう一つの問題を考えてみましょう.役割ドメインはコードの作成時に決定されたのでしょうか.それともコードの実行過程で決定されたのでしょうか.
var carName = "Volvo";
// carName
function myFunction(){
// carName
}
このコードを見て、コードを書くときにcarNameがグローバル役割ドメインであり、関数内部のvarで定義された変数が関数役割ドメインであることがわかります.これは専門用語です.文法の役割ドメインです.
一般的に変数の役割ドメインは定義時に決定され、実行時に決定されるのではなく、すなわち文法の役割ドメインはソースコードに依存し、静的解析によって決定されるため、文法の役割ドメインは静的役割ドメインとも呼ばれる.
逆に,変数の役割ドメインは実行段階でしか決定できない,すなわち動的役割ドメインである.
次のコードは動的役割ドメインに従っているのか、それとも静的役割ドメインに従っているのかを見てみましょう.
function foo(){
console.log(a) //2 ( 3!)
}
function bar(){
var a=3;
foo();
}
var a=2;
bar()
どうしてこんなことになったの?
動的役割ドメイン解析に従うと、foo()がaの変数参照を解析できない場合、ネストされた役割ドメインチェーンに沿って1つ上へ行くのではなく、呼び出しスタックに沿って上へ行ってfoo()がどこから呼び出されたかを見つけることができます.foo()はbar()から呼び出されるため、bar()の役割ドメインで変数をチェックし、ここで値3を持つaを見つけます.
静的役割ドメイン解析:fooが実行されたときにaという変数が見つからなかった場合、コードの書く順序で上を探します.つまりfoo定義の外層は、foo呼び出しのbar内ではなくvar a=2を見つけます.
だから結果は2です.
この例からJavaScriptのデフォルトでは、動的な役割ドメインを開くにはbind、with、evalなどを使用します.