Home > Web Front-end > JS Tutorial > body text

javascript nested functions (scope chain)_javascript skills

WBOY
Release: 2016-05-16 18:32:36
Original
1048 people have browsed it

Nested functions (scope chain)
When you nest functions, be aware that the scope chain actually changes, which may not seem intuitive. You can put the following code into firebug to monitor value changes.

Copy code The code is as follows:

var testvar = 'window attribute';
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 property'
alert('o3-inner: ' this.testvar2);/ /undefined (undefined)
};
inner();
}
};
o3.fun();

Here we have changed function, this function is almost similar to the original function, but the difference is the way the internal function is written. It should be noted that the scope in which the internal function runs is different from the scope of the external function. Ext allows you to specify the scope of the function when calling the function to avoid scope problems.
Declaration of variables
Be sure to add the "var" keyword when initializing a variable. Otherwise, it is a global variable. For example, in the following example, there will be a variable written inside the function. However, you intend to only declare the local variable, but it may actually overwrite the value of the global variable. In the FIREBUG "DOM" tab, you can see all global variables by examining "window". If you find that there is a "k" or "x" variable, it means that you have allocated this variable in an inappropriate scope. See the example below:
Copy code The code is as follows:

var i = 4;
var j = 5;
var k = 7;
var fn = function(){
var i = 6;
k = 8;//Note that there is no var in front, so the meaning of this sentence Assign 8 to variable k!
alert(i);//6
alert(j);//5
alert(k '-1');//8-1
x = 1;//This sentence There are two situations, creating all variables x or overwriting all variables x
};
fn();
alert(k '-2'); //8-2 (Note Not 7-2)

Not much changed from the previous example. Also note that there is no var keyword in front of k in the function, so instead of declaring a local variable, a certain value is Assign it to the global variable k again. Another thing to note is that during the execution of the alert method, parameter i is a local variable that can currently be found, and its value is 6, but parameter j cannot be found in the current scope, so it searches upward along the scope chain. , until the j of the global variable is found.
Specify scope in Ext
As mentioned earlier, Ext can flexibly handle scope issues when calling functions. Part of the content comes from dj's post.
When calling a function, you can think of this as a special (hidden) parameter within each function. Whenever, JavaScript will put this inside the function. It is based on a very simple idea: if the function is directly a member of an object, then the value of this is this object. If the function is not a member of an object, then the value of this is set to some global object (commonly, the window object in the browser). This idea can be clearly seen in the internal function below.
If a function is assigned to a variable, that is, it is not a member of any object, then the parameter of this becomes a windows object. The following is an example that can be pasted directly into the Firebug console:
Copy the code The code is as follows:

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();
  }
}; 🎜>obj.func();
// Output "within the scope of obj (within the scope)"
// Output "some related content of Window..."

Missing This saves calling a parameter like this - but you can also change this parameter manually, but the syntax is slightly different. Change the "obj.func();" in the last line to:

Copy the code The code is as follows:
obj.func.call(window);
// Output "Some related content of Window..."
// Output "Some related content of Window..."

As can be seen from the above example, call is actually another function (method). call belongs to the system's built-in method for obj.func (according to the characteristics of JavaScript, we know that a function is an object.).
By changing the scope pointed to by this in this way, we can continue to use an example to correct the this parameter in innerFunc - the "incorrect" pointing:

Copy the code The code is as follows:
var obj = {
toString:function(){ return 'within the scope of obj (within the scope)';}, //Rewrite the toString function to facilitate the output when executing console.log(this)
func: function(){
);
innerFunc.call(this);
}
};
obj.func();
// Output "Within the scope of obj (within the scope)"
// Output "Within the scope of obj (within the scope)"


Scope configuration of Ext
You can see that there is no function that assigns a scope, and its "this" points to the browser's window object (Such as event handler, etc.), unless we change the pointer of this. In many Ext classes, scope is a configuration item that can be used for pointer binding. For related examples, refer to
. Ext's createDelegate function
* In addition to the built-in call/apply method, Ext also provides us with the helper method createDelegate. The basic function of this function is to bind this pointer but not execute it immediately by passing in a parameter to the createDelegate method. It will ensure that the function runs in the scope of this parameter. For example:



Copy the code

The code is as follows:

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
The code is as follows: varsDs.load({callback: function(records){ col_length = varsDs.getCount();//The varDs here left the scope? //col_length = this.getCount();/ /Is this equal to store?
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.
Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template