Nested functions (scope chain)
When nesting a function, you must note that the scope chain actually changes, which may not seem intuitive. You can Code Changes in the monitoring value of firebug.
Copy code The Code is as follows: var testvar = 'window properties ';
VaR O1 = {testvar: '1', fun: function () {alert ('o1: '+ this. testvar +' <');}};
VaR O2 = {testvar: '2', fun: function () {alert ('o2: '+ this. testvar );}};
O1.fun (); '1'
O2.fun (); '2'
O1.fun. Call (O2); '2'
This is the first example in this article. copy Code the code is as follows: vaR testvar = 'window attribute';
var O3 = {
testvar: '3',
testvar2: '3 ** ',
fun: function () {
alert ('o3: '+ this. testvar); // 'obj3'
var inner = function () {
alert ('o3-inner: '+ this. testvar); // 'window attribute'
alert ('o3-inner: '+ this. testvar2); // undefined (undefined)
};
Inner ();
}< BR >};
o3.fun ();
here we have changed other functions. This function is almost similar to the original function, but the difference is the writing of internal functions. It should be noted that the scope of the internal function Runtime is different from that of the external function. EXT allows you to specify the function scope when calling a function to avoid scope problems.
variable declaration
when initializing a variable, you must add the "Var" keyword. If not, this is a global variable. For example, in the following example, a variable is written inside the function. However, you only intend to declare a local variable, but it may also overwrite the value of the global variable. On the firebug "dom" tab, you can check "window" to view all global variables. If you find that there is a "K" or "x" variable, it proves that you have allocated this variable to an inappropriate scope. See the following example: copy Code : vaR I = 4;
var J = 5;
var K = 7;
var fn = function () {
var I = 6;
K = 8; // note that no var exists before. Therefore, 8 is assigned to variable k!
alert (I); // 6
alert (j); // 5
alert (K + '-1 '); // 8-1
x = 1; // This statement can be used to create all variables X or overwrite all variables X
};
FN ();
alert (K + '-2'); // 8-2 (note not 7-2)
the preceding example does not change much. Note that there is no var keyword before K in the function, so the local variable is not declared here, instead, it allocates a value to the global variable k. In addition, during the alert method execution, parameter I is a local variable that can be found currently. Its value is 6, but parameter J cannot be found in the current scope, search up the scope chain until the J of the global variable is found.
specify the scope in ext
As mentioned earlier, ext can flexibly handle the scope issue when calling a function. Some of the content comes from DJ posts.
when calling a function, you can think of this as a special (hidden) parameter in each function. At any time, JavaScript will put this inside the function. It is based on a very simple idea: If a function is directly a member of an object, the value of this is the object. If a function is not a member of an object, the value of this is set to a global object (commonly, a window object in a browser ). The following internal functions clearly show this idea.
If a function is assigned to a variable, that is, it does not belong to a member of any object, then this parameter is changed to a Windows Object. The following is an example that can be directly pasted to the firebug Console: copy Code the code is as follows: var OBJ = {
tostring: function () {return 'obj in scope (in scope) ';}, // rewrite the tostring function to facilitate console execution. log (this) Output
FUNC: function () {
// The function here is directly subordinate to the object "object"
console. log (this);
var innerfunc = function () {
// n the function here is not a direct member of a specific object, it's just a variable of another function
console. log (this);
};
innerfunc ();
}< BR >};
obj. func ();
// output "OBJ in scope (in scope)"
// output "Window related content... "
By default, a parameter is called like this-but you can also manually change this parameter, but the syntax is slightly different. Change "obj. func ();" in the last row:Copy codeThe Code is as follows: obj. func. Call (window );
// Output "some related content of window ..."
// Output "some related content of window ..."
From the above example, we can find that call is actually another function (method ). Call is a built-in method of obj. func. (according to the characteristics of JavaScript, a function is an object .).
By changing the scope that this points to, we can continue to use an example to correct the this parameter in innerfunc, which is "Incorrect:Copy codeThe Code is as follows: var OBJ = {
Tostring: function () {return 'obj's range (in scope) ';}, // rewrite tostring function to facilitate output during console. Log (this) Execution
FUNC: function (){
// The function here is directly subordinate to the object "object"
Console. Log (this );
VaR innerfunc = function (){
// N the function here is not a direct member of a specific object, but a variable of another function.
Console. Log (this );
};
Innerfunc. Call (this );
}
};
OBJ. func ();
// Output "OBJ in scope (in scope )"
// Output "OBJ in scope (in scope )"
ext scope configuration
you can see that there is no function with scope assigned. This "indicates the window object of the browser (such as event handle event handler ), -- unless we change the pointer of this. In many classes of Ext, scope is a configuration item that can bind pointers. For relevant examples, see Ajax. Request.
ext's createdelegate function
* In addition to the built-in call/apply method, ext also provides the -- auxiliary method createdelegate. The basic function of this function is to bind the this pointer but not execute it immediately. Input a parameter. The createdelegate method ensures that the function runs in the scope of this parameter. For example, the copy Code code is as follows: vaR OBJ = {
tostring: function () {return 'obj's range (in scope) ';}, // rewrite the tostring function to facilitate console execution. log (this) Output
FUNC: function () {
// The function here is directly subordinate to the object "object"
console. log (this);
var innerfunc = function () {
// n the function here is not a direct member of a specific object, it's just a variable of another function
console. log (this);
};
innerfunc = innerfunc. cr Eatedelegate (this); // here we use the delegate function to overwrite the original function.
innerfunc (); // call the function according to the general syntax
}< BR >};
obj. func ();
// output "OBJ in scope (within scope)"
// output "OBJ in scope (within scope)"
This is a small example. Its principle is very basic and I hope it can be well digested. Even so, in practical work, we are still confused, but basically, if we can analyze the ins and outs according to the above theoretical knowledge, we will not leave them alone.
here is another example: copy Code the code is as follows: varsds. load ({callback: function (Records) {
col_length = varsds. getcount (); // is vards out of scope?
// col_length = This. getcount (); // is this equal to store?
for (VAR x = 0; x {< br> colarray [x] = varsds. getat (X ). get ('hex');
}< BR >}}); but it can be clearly written:
var OBJ ={< br> callback: function (Records) {
col_length = varsds. getcount (); // is vards out of scope?
// col_length = This. getcount (); // is this equal to store?
//...
}< BR >};
Varsds. Load (OBJ); now the callback function is directly attached to OBJ, so this pointer is equal to OBJ.
But note: this is useless. Why? Because you do not know what will happen when obj. Callback is executed. Imagine the load method of Ext. Data. Store (implementation of imitation ):Copy codeThe Code is as follows :...
Load: function (config ){
VaR o = {};
O. Callback = config. Callback;
// Load
O. Callback ();
}
...
In this counterfeit implementation, the callback function has the scope of the private variable "O ". Generally, you cannot know how a function is called. If the scope is not declared, you may not be able to use this parameter in the callback function.