ネストされた関数 (スコープ チェーン)
関数をネストするときは、スコープ チェーンが実際に変更されることに注意してください。これは直観的ではないかもしれません。次のコードを firebug に挿入して、値の変更を監視できます。
var testvar = 'ウィンドウ属性'; 🎜>var o1 = {testvar:'1', fun:function(){alert('o1: ' this.testvar '<<');}};
var o2 = {testvar:'2' 、楽しい: function(){alert('o2: ' this.testvar);}};
o1.fun();'1'
o2.fun();'2'
o1。 fun.call (o2);'2'
これは、この記事の最初の例です。
var testvar = 'ウィンドウ属性'; 🎜>var o3 = {
testvar:'3',
testvar2:'3**',
fun:function(){
alert('o3: ' this.testvar);/ /'obj3 '
var inner = function(){
alert('o3-inner: ' this.testvar);//'ウィンドウ プロパティ'
alert('o3-inner: ' this.testvar2 );/ /未定義 (未定義)
inner();
}
};
変更された関数、この関数は元の関数とほぼ似ていますが、内部関数の記述方法が異なります。内部関数が実行されるスコープは外部関数のスコープとは異なることに注意してください。 Ext を使用すると、関数を呼び出すときに関数のスコープを指定して、スコープの問題を回避できます。
変数の宣言
変数を初期化するときは必ず「var」キーワードを追加してください。それ以外の場合はグローバル変数です。たとえば、次の例では、関数内に変数が記述されていますが、ローカル変数を宣言するだけのつもりですが、実際にはグローバル変数の値が上書きされる可能性があります。 FIREBUG の「DOM」タブで、「window」を調べるとすべてのグローバル変数が表示されます。 「k」または「x」変数があることがわかった場合は、この変数が不適切なスコープに割り当てられていることを意味します。以下の例を参照してください:
コードをコピー
var fn = function(){
var i = 6;// var がないことに注意してください。が前にあるので、この文の意味 変数 k に 8 を代入してください!
alert(i);//6
alert(j);//5
alert(k '-1');//8-1
x = 1;//この文すべての変数 x を作成するか、すべての変数 x を上書きするかの 2 つの状況があります。
fn()
alert(k '-2');
関数内の k の前に var キーワードがないため、ローカル変数を宣言する代わりに、特定の値がグローバル変数に割り当てられることにも注意してください。再び変数k。もう 1 つ注意すべき点は、アラート メソッドの実行中、パラメータ i は現在見つかっているローカル変数であり、その値は 6 ですが、パラメータ j は現在のスコープで見つからないため、スコープに沿って上向きに検索されることです。グローバル変数の j が見つかるまで連鎖します。
Ext でスコープを指定する
前述したように、Ext は関数を呼び出すときにスコープの問題を柔軟に処理できます。内容の一部はDJの投稿から引用しています。
関数を呼び出すとき、これを各関数内の特別な (隠し) パラメーターと考えることができます。 JavaScript は常にこれを関数内に置きます。これは非常に単純な考えに基づいています。関数が直接オブジェクトのメンバーである場合、this の値はこのオブジェクトになります。関数がオブジェクトのメンバーではない場合、this の値は何らかのグローバル オブジェクト (通常はブラウザ内のウィンドウ オブジェクト) に設定されます。この考え方は、以下の内部関数で明確に見ることができます。
関数が変数に割り当てられている場合、つまり、関数がどのオブジェクトのメンバーでもない場合、そのパラメータは Windows オブジェクトになります。以下は、Firebug コンソールに直接貼り付けることができる例です:
コードをコピーします
コードは次のとおりです:
var obj = {
toString:function(){ return 'obj のスコープ内 (スコープ内)';}, //console.log( の実行を容易にするために toString 関数を書き換えます) this) Output
func: function(){
// ここでの関数はオブジェクト "object" に直接従属します
console.log(this);
var innerFunc = function(){
// nここでの関数は特定のオブジェクトの直接のメンバーではなく、別の関数の単なる変数です
};
innerFunc(); }
}; 🎜>obj.func();
// 「obj のスコープ内 (スコープ内)」を出力
// 「Window の一部の関連コンテンツ」を出力
Missing これにより、このようにパラメータを呼び出す手間が省けます。ただし、このパラメータを手動で変更することもできますが、構文は若干異なります。最後の行の「obj.func();」を次のように変更します:
// 出力 "Window の関連コンテンツ..."
// 出力 "Window の関連コンテンツ..."
上記の例からわかるように、call は実際には別の関数 (メソッド) です。 call は、obj.func のシステム組み込みメソッドに属します (JavaScript の特性によれば、関数はオブジェクトであることがわかっています)。
このように this が指すスコープを変更することで、innerFunc の this パラメータ、つまり「間違った」ポインティングを修正する例を引き続き使用できます:
toString:function(){ return 'obj のスコープ内 (範囲内)スコープ)';}, //console.log(this)
func: function(){
);
innerFunc.call(this); 🎜> }
};
obj.func();
// 出力 "obj のスコープ内 (スコープ内)"
// 出力 "obj のスコープ内 (スコープ内)スコープ)"
Ext
のスコープ設定 スコープを割り当てる関数はなく、その「this」がブラウザのウィンドウオブジェクト (イベントハンドラーなど) を指していることがわかります。 .) のポインタを変更しない限り、スコープはポインタのバインディングに使用できる設定項目です。関連する例については、Ext の createDelegate 関数
を参照してください。組み込みの call/apply メソッドと同様に、Ext はヘルパー メソッド createDelegate も提供します。この関数の基本的な機能は、このポインターをバインドすることですが、関数を createDelegate メソッドにパラメーターを渡すことですぐに実行しないようにすることです。例:
コードをコピーします。
コードは次のとおりです。
var obj = {
toString:function(){ return 'within the scope of obj (within the scope)';}, //Rewrite the toString function to facilitate the execution of console.log(this) Output
func: function(){
// The function here is directly subordinate to the object "object"
console.log(this);
var innerFunc = function(){
// nThe function here is not a direct member of a specific object, it is just a variable of another function
console.log(this);
};
innerFunc = innerFunc.createDelegate(this); // Here we use The delegated function overrides the original function.
. 🎜>// Output "within the scope of obj"
This is a small example, the principle is very basic, I hope you can digest it well. Despite this, in real work, we are still easily confused, but basically, if we can analyze the ins and outs according to the above theoretical knowledge, everything will change.
There is another thing, take a look at the following example:
Copy the code
for (var x = 0; x < col_length; x )
{
colarray[x] = varsDs.getAt(x).get('hex');
}
}}); However, it can be written more clearly:
var obj = {
callback: function(records){
col_length = varsDs.getCount();//here varDs went out of scope?
//col_length = this.getCount();//Is this equal to store?
// ...
}
};
varsDs.load(obj); Now the function callback is directly hung on obj, so the this pointer is equal to obj.
But note: This is useless. Why? Because you don't know what will happen when obj.callback is finally executed. Just imagine the load method of Ext.data.Store (imitation implementation):
Copy the code
The code is as follows: ... load : function(config) { var o = {};
o.callback = config.callback;
//Load
o.callback ();
}
...
In this fake implementation, the scope of the callback function is the private variable "o". Because you usually don't know how the function is called, if you don't declare the scope, you probably won't be able to use this parameter in the callback function.