JavaScript advanced programming (version 3rd) learning notes 8 js functions (medium)

Source: Internet
Author: User

6. Execution Environment and scope

(1) execution context: All JavaScript code runs in one execution environment. When control is transferred to the executable code of JavaScript, it enters an execution environment. The execution environment of the activity logically forms a stack. The Global execution environment is always the bottom element of the stack, and the top element of the stack is the running execution environment. Each function has its own execution environment. When the execution flow enters a function, the execution environment of the function is pushed to the top of the stack. After the function is executed, the execution environment is displayed, control is returned to the previous execution environment.

(2) variable object: Each execution environment has a corresponding variable object. All variables and functions defined in the execution environment are stored in this variable object. This variable object is an object in the background implementation and cannot be accessed in the code, but it helps us understand the concept of execution environment and scope.

(3) scope chain: When code runs in an execution environment, a scope chain composed of variable objects is created. The front end of this chain is the variable object in the environment where the current code is located. The end of the chain is the variable object in the global environment. When the identifier is parsed in an execution environment, it will be searched in the corresponding variable object in the current execution environment. If it is found, it will be returned, if no value is found, the system searches for the variable objects in the global environment at the level of the scope chain. If no value is found, a reference exception is thrown.

(4) activation object: if an execution environment is a function execution environment, the variable object is also called an activity object. The activity object contains only one variable at the beginning, that is, the arguments object (this object does not exist in the global environment variable object ).

Although these four concepts are somewhat abstract, they are still quite natural. You can take a closer look at them in an example in JavaScript advanced programming (version 3rd:
Copy codeThe Code is as follows:
// Enter the global scope to create a global variable object
Var color = "blue ";

Function changeColor (){
// Enter the changeColor scope and create the variable object of changeColor.
Var anotherColor = "red ";

Function swapColors (color1, color2 ){
// Enter the swapColors scope and create the swapColors variable object.
Var tempColor = anotherColor;
AnotherColor = color;
Color = tempColor;
/*
* SwapColors:
* Color and changeColor of the global variable object
* The changeColor function specifies the anotherColor and swapColors of the corresponding variable objects.
* The tempColor of the corresponding variable object of the swapColors Function
*/
}
SwapColors ('white ');
/*
* The following objects can be accessed in the changeColor scope:
* Color and changeColor of the global variable object
* The changeColor function specifies the anotherColor and swapColors of the corresponding variable objects.
*/
}

ChangeColor ();
/*
* Objects that can be accessed in the global scope are:
* Color and changeColor of the global variable object
*/

The entire process here is:

(1) enter the global environment, create a global variable object, and press the global environment to the top of the stack (this is also the bottom of the stack ). According to the preceding Declaration and promotion conclusion, the possible process for creating a global variable object here is to first create a local variable object, and then process the function declaration to set the attribute changeColor as the corresponding function, then process the variable Declaration and set the attribute color to undefined.

(2) execute the code in the global environment. First, initialize the color variable, assign the value to 'Blue ', and then call the changeColor () function.

(3) Call the changeColor () function to enter the changeColor function execution environment, create a variable object (activity object) corresponding to the environment, and press the environment to the top of the stack. One possible process for creating an activity object is to first create an activity object, process the internal function declaration, set the swapColors attribute as the corresponding function, and process the function parameters to create the activity object's attribute arguments object, processing internal variable Declaration sets the attribute anotherColor to undefined.

(4) execute the changeColor () function code. Run anotherColor to initialize to 'red', and then call the swapColors () function.

(5) Call the swapColors () function to enter the swapColors function execution environment, create the corresponding variable object (activity object), and press the swapColors execution environment to the top of the stack. A possible process for creating an activity object here is to first create an activity object, process function parameters, take the form parameter as the property of the activity object, and assign the value to undefined to create the arguments Object Property of the activity object, and according to the actual parameter initialization form parameter and the value and attribute corresponding to arguments (initialize the color1 and arguments [0] attributes to 'white', because there is no second actual parameter, so the value of color2 is undefined, and the length of arguments is only 1). After processing the function parameters, process the internal variable Declaration of the function, use tempColor as the property of the activity object and assign it to undefined.

(6) run the swapColors () function code. Initialize and assign values to tempColor, and then implement the value exchange function (here the values of color and anotherColor are read along the scope chain ).

(7) after the swapColors () function code is executed, undefined is returned, and the corresponding execution environment pops up and is destroyed (Note: The execution environment will be destroyed here, but the activity objects in the execution environment are not necessarily destroyed.) The current execution environment is restored to the execution environment of the changeColor () function. After the swapColor () function is executed and returned, changeColor () is executed, undefined is returned, and the execution environment of changeColor () function is popped up and destroyed, the current execution environment is restored to the global environment. The entire process ends, and the global environment ends until the page is exited and then destroyed.

The scope chain also explains why a function can call itself recursively within a function: the function name is an attribute of the corresponding variable object in the execution environment where the function is defined, and then in the internal execution environment of the function, you can access the function object directed by the function name along the scope chain. If the function name is directed to a new function within the function, it will be incorrect during recursive calling:
Copy codeThe Code is as follows:
Function fn (num ){
If (1 = num ){
Return 1;
} Else {
Fn = function (){
Return 0;
};
Return num * fn (num-1 );
}
}
Console.info (fn (5); // 0

For more information, see the following example:
Copy codeThe Code is as follows:
Var name = 'linjisong ';
Function fn (){
Console.info (name); // undefined
Var name = 'external ';
Console.info (name); // oulinhai
}
Fn ();
Console.info (name); // linjisong

The least intuitive here is probably the 3rd rows output undefined, because the name has been defined in the global, but the correct result can be obtained by parsing it once according to the above parsing steps. In addition, in ECMAScript, only the global execution environment and function execution environment are available, and the corresponding global scope and function scope are available. There is no block scope-although there are block statements.
Copy codeThe Code is as follows:
Function fn (){
Var fnScope = 'a ';

{
Var blockScope = 'B ';
BlockScope + = fnScope;
}
Console.info (blockScope); // No block scope, so you can access blockScope within the entire function Scope
Console.info (fnScope );
}
Fn (); // ba,

Console.info (blockScope); // ReferenceError, out of function scope, cannot access internally defined Variables
Console.info (fnScope); // ReferenceError

For the scope chain, you can also use catch blocks of with and try-catch statements to extend them:

• When you use the with (obj) {} statement, add the obj object to the frontend of the current scope chain.
• When you use the try {} catch (error) {} statement, add the error object to the frontend of the current scope chain.
I inserted a relatively abstract concept, hoping that it would not affect the overall reading smoothness. In fact, I quietly bypassed a concept called "closure" here. Regarding functions and closures, in the next article, I will describe it in detail.

7. Internal function objects and this

For users of the object-oriented language, this is really not familiar. Isn't it just pointing to the newly created object of the constructor! However, in ECMAScript, do not take it lightly. It is not that simple. Although this does point to a new object when a function is called using the new operator, however, this is only one way to specify the value of this object. There are more ways to specify the value of this object. In other words, this is dynamic, it can be set by ourselves.

(1) this in the global environment

In the global environment, this points to the global object itself, which is also a window in the browser. Here, we can also regard this in the global environment as a variable object corresponding to the global execution environment, the variables and functions defined in the global environment are the attributes of the variable object:
Copy codeThe Code is as follows:
Var vo = 'a ';
VO 2 = 'B ';
Function fn (){
Return 'fn ';
}
Console.info (this = window); // true
Console.info (this. vo); //
Console.info (this. VO); // B
Console.info (this. fn (); // fn

If you want to reference a global object in a user-defined function, although you can use window directly, it is better to pass the global object as a parameter to the function, this is a very common method in the JS Library:
Copy codeThe Code is as follows:
(Function (global ){
Console.info (global = window); // you can use global internally to replace window.
}) (This );

This method has better compatibility (global Objects may not all be windows in ECMAScript Implementation). During compression, you can also simplify global to g without using Windows.

(2) internal function attribute this

In the function environment, this is an internal property object. It can be understood as an attribute of the activity object corresponding to the function, and the value of this internal property is dynamic. Then how is this value dynamically determined?

• When a new call is used, a function is also called a constructor. In this case, this inside the function is specified as a newly created object.
Copy codeThe Code is as follows:
Function fn (){
Var name = 'external'; // the property of the activity object corresponding to the Function
This. name = 'linjisong'; // when using new to call a function, this is specified as a newly created object, that is, adding attributes to the newly created object.
}
Var person = new fn ();
Console.info (person. name); // linjisong

Var arr = [fn];
Console.info (arr [0] (); // undefined

Note that the attributes defined in the function execution environment (that is, the attributes of the activity object) and the attributes of this object are distinguished. When using array elements to call a function, this inside the function points to the array itself, so the undefined output in the above example is final.

• As a general function call, this points to a global object.
• When called as an object's method, this points to the object that calls this method.
See the following example:
Copy codeThe Code is as follows:
Var name = 'external ';
Var person = {
Name: 'linjisong ',
GetName: function (){
Return this. name;
}
};
Console.info (person. getName (); // linjisong
Var getName = person. getName;
Console.info (getName (); // oulinhai

Here, the function object itself is anonymous and serves as an attribute of the person object. When called as an object property, this points to the object. When this function is assigned to another function and then called, is called as a common function. this points to a global object. This example fully demonstrates that "when a function is called as an object's method, the internal attribute this points to this called object. When a function is called as a general function, the internal attribute this points to a global object ", it also shows that this is dynamically specified during the call, regardless of whether the function is defined separately or as an object method. This is precisely because this points to the called object when a function is called as an object method, therefore, when the function returns this internally, the next method of the called object can be continued-that is, the chain operation (a major feature of jQuery ).

• When you call a function using apply (), call (), or bind (), this points to the first parameter object. If no parameter is input or null or undefined is input, this points to the Global Object (it is set to null in ES5 strict mode ). If the first parameter is a simple type, this is set as the corresponding simple type packaging object.
Copy codeThe Code is as follows:
Var name = 'linjisong ';
Function fn (){
Return this. name;
}
Var person = {
Name: 'external ',
GetName: fn
};
Var person2 = {name: 'hujsoning '};
Var person3 = {name: 'huanglanxue '};
Console.info (fn (); // linjisong, a common function call. The internal attribute "this" points to a global object. Therefore, linjisong is returned for this. name.
Console.info (person. getName (); // oulinhai, called as an object method. this points to this object, so the person. name is returned here.
Console.info (fn. apply (person2); // hujinxing, use apply, call, or bind to call the function and execute the first input parameter object. Therefore, the returned person2.name
Console.info (fn. call (person2); // hujinxing
Var newFn = fn. bind (person3); // The New Method in ES5 creates a new function instance and returns the result. The internal value of this is specified as the input parameter object.
Console.info (newFn (); // huanglanxue

The preceding example lists common cases. If the first parameter is null or undefined, you can test it yourself. For the determination of this value, there is an example in the original book:
Copy codeThe Code is as follows:
Var name = 'The window ';
Var object = {
Name: 'My object ',
GetName: function (){
Return this. name;
},
GetNameFunc: function (){
Return function (){
Return this. name;
}
}
};

Console.info (object. getName (); // My Object
Console.info (object. getName) (); // My Object
Console.info (object. getName = object. getName) (); // The Window
Console.info (object. getNameFunc (); // The Window

1st are normal output and 2nd (object. getName) and object. the getName effect is the same, while the 3rd (object. getName = object. getName) the final return is the function object itself, that is to say, 3rd will be called as general functions, and 4th will first call the getNameFunc method, return a function, and then call this function, it is also called as a common function.

8. Function Attributes and Methods

A function is an object, so it can have its own attributes and methods. However, Function Attributes and methods are easily confused with internal functions. Since they are easy to be confused, we can put them together for comparison. This is like a pair of twins, unfamiliar people cannot be differentiated.

First, the concept is as follows:

(1) internal function attributes: it can be understood as the attribute of the corresponding function activity object, which can only be accessed from the function body. Each time a function is called, it will be re-specified, dynamic.

(2) Function Attributes and Methods: This is a feature of a function as an object. As long as a function is defined, the function object is created and the corresponding attributes and methods can be accessed, and unless you explicitly assign another value in the Code, their values will not change, so they are static. There is an exception property caller, which indicates the function that calls the current function. It is also dynamically specified when the function is called. In JavaScript advanced programming (version 3rd) therefore, the caller attribute and the internal function attributes arguments and this are explained together. In fact, in the strict mode of ES5, caller attributes with dynamic characteristics cannot be assigned a value.

In terms of concept, the distinction between light and light is very abstract and not so easy to understand. Then, we can compare these attributes together (not including some non-standard attributes, such as name ):

Category Name Inheritance Description Remarks
Internal Function Attributes This - Environment object where function data is executed Very different from general object-oriented languages
Arguments -

Array object that represents the actual function parameters

Arguments also has its own attributes: length, callee, and caller.

1. The length attribute indicates the number of actually received parameters.

2. The callee attribute points to the function object itself, I .e:

Fn. arguments. callee = fn

3. The caller attribute is mainly distinguished from the caller of the function. The value is always undefined.

Function attribute Caller No Function that calls the current function Although the function can be accessed in a certain sense, it is always null when it is not accessed in the function body. When it is accessed in the function body, the function that calls the current function is returned. In the global scope, the function will return null.
Length No Length of function form parameters Is the number of parameters that are named when the function is defined.
Prototype No Function prototype object Prototype objects are the basis for ECMAScript to implement inheritance.
Constructor Yes It is inherited from an Object, indicating the Function used to create a Function instance, that is, Function () The value is always a Function, that is, the built-in Function ()
Function Method Apply No Call the function itself and accept parameters in the form of (class) Arrays

These three methods are mainly used to dynamically bind the internal attribute of the function. this

1. apply and call will be executed immediately after binding

2. bind can be called and executed as needed after binding

Call No Call the function itself to accept parameters by listing
Bind No Bound function scope, added in ES5
ToLocalString Overwrite

Overwrites the methods in the Object type and returns the function body.

Different browsers may return different results, the original code may be returned, or the Code removed from the comment may be returned.

ToString Overwrite
ValueOf Overwrite
HasOwnProperty Yes The method that directly inherits from the Object type. Its usage is the same as that of the Object.
PropertyIsEnumerable Yes
IsPropertyOf Yes

Function Attributes and methods, in addition to the attributes and methods inherited from the Object, and also include the attributes and Methods unique to the function itself. The most commonly used methods are actually the apply () mentioned in the previous section () and call (), both of which are used to set the internal attribute of the function. this expands the function scope, except that the parameters of the function are accepted in the (class) array when applying () The function scope, when calling () extends the function scope, function parameters must be listed one by one for transmission. See the following example:

Copy codeThe Code is as follows:
Function sum (){
Var total = 0,
L = arguments. length;

For (; l --){
Total + = arguments L-1 1];
}
Return total;
}

Console.info (sum. apply (null, [1, 2, 3, 4]); // 10
Console.info (sum. call (null, 1, 2, 3, 4); // 10

But it should be emphasized that the main function of apply and call is to extend the function scope. The apply and call functions immediately when the scope is extended, which makes the application very limited. Therefore, a new bind () function is added in ES5, which is also used to extend the scope, however, you do not need to execute the function immediately. It returns a function instance and uses the first parameter passed to it as the scope of the original function. One of its possible implementations is as follows:
Copy codeThe Code is as follows:
Function bind (scope ){
Var that = this;
Return function (){
That. apply (scope, arguments );
}
}
Function. prototype. bind = bind;

The concept of a closure is involved here, and we will continue tomorrow.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.