Overview Functions are the basis for modular programming. To write complex Ajax applications, you must have a deeper understanding of functions. Functions in JavaScript are different from other languages. Each function is maintained and run as an object. Through the properties of function objects, you can easily assign a function to a variable or pass the function as a parameter. Before continuing, let’s take a look at the syntax of using functions:
function func1(…){…}
var func2=function(…){…};
var func3=function func4(…){ …};
var func5=new Function();
These are correct syntax for declaring functions. They are very different from common functions in other languages or the function definition methods introduced before. So why can it be written like this in JavaScript? What is the syntax it follows? These are described below.
Understand Function Object You can use the function keyword to define a function, specify a function name for each function, and call it through the function name. When JavaScript is interpreted and executed, functions are maintained as an object, which is the Function Object to be introduced.
Function objects are essentially different from other user-defined objects. This type of object is called an internal object. For example, date object (Date), array object (Array), and string object (String) are all internal objects. object. The constructors of these built-in objects are defined by JavaScript itself: by executing a statement such as new Array() to return an object, JavaScript has an internal mechanism to initialize the returned object, instead of the user specifying how the object is constructed.
In JavaScript, the corresponding type of function object is Function, just like the corresponding type of array object is Array and the corresponding type of date object is Date. You can create a function object through new Function(), or you can use the function key words to create an object. For ease of understanding, we compare the creation of function objects with the creation of array objects. Let’s look at the array object first: The following two lines of code both create an array object myArray:
var myArray=[];
//Equivalent to
var myArray=new Array();
Similarly, The following two pieces of code also create a function myFunction:
function myFunction(a,b){
return a b;
}
//Equivalent to
var myFunction=new Function ("a","b","return a b");
By comparing it with the statement to construct an array object, you can clearly see the nature of the function object. The function declaration introduced earlier is the first way of the above code. Inside the interpreter, when encountering this syntax, a Function object will be automatically constructed and the function will be stored and run as an internal object. It can also be seen from here that a function object name (function variable) and an ordinary variable name have the same specifications. Both can refer to the variable through the variable name, but the function variable name can be followed by parentheses and a parameter list to perform the function. call.
It is not common to create a function in the form of new Function(), because a function body usually has multiple statements. If they are passed as parameters in the form of a string, the readability of the code will be poor. The following is an introduction to its usage syntax:
var funcName=new Function(p1,p2,...,pn,body);
The types of parameters are all strings, and p1 to pn represent the parameter names of the created functions. List, body represents the function body statement of the created function, and funcName is the name of the created function. You can create an empty function without specifying any parameters, and create an unnamed function without specifying funcName. Of course, such a function has no meaning.
It should be noted that p1 to pn are lists of parameter names, that is, p1 can not only represent a parameter, it can also be a comma-separated parameter list. For example, the following definitions are equivalent:
new Function("a", "b", "c", "return a b c")
new Function("a, b, c", "return a b c")
new Function("a,b", "c", "return a b c")
JavaScript introduces the Function type and provides syntax like new Function() because function objects must use the Function type to add properties and methods.
The essence of a function is an internal object, and the JavaScript interpreter determines how it operates. The function created by the above code can be called using the function name in the program. The function definition issues listed at the beginning of this section are also explained. Note that you can add parentheses directly after the function declaration to indicate that the function is called immediately after creation, for example:
var i=function (a,b){
return a b;
}(1,2) ;
alert(i);
This code will display that the value of variable i is equal to 3. i represents the returned value, not the created function, because the brackets "(" have a higher priority than the equal sign "=". Such code may not be commonly used, but when the user wants to This is a good solution for modular designs or if you want to avoid naming conflicts.
It should be noted that although the following two methods of creating functions are equivalent:
function funcName(){
// Function body >var funcName=function(){
//Function body
}
But the former method creates a named function, and the latter creates an unnamed function, just letting a variable point to the unnamed function function. There is only one difference in usage: for a named function, it can be defined after it is called; while for an unnamed function, it must be defined before it is called. For example:
This statement will generate an undefined error for func, but:
can be executed correctly, and the following statement can also be executed correctly:
It can be seen that although JavaScript is an interpreted language, it will check whether there is a corresponding function definition in the entire code when a function is called. This function name can only be defined in the form of function funcName() will be valid, not an anonymous function.
The relationship between function objects and other internal objects
In addition to function objects, there are many internal objects, such as: Object, Array, Date, RegExp, Math, Error. These names actually represent a type, and an object can be returned through the new operator. However, function objects are different from other objects. When typeof is used to get the type of a function object, it will still return the string "function", and when typeof an array object or other object, it will return the string "object". The following code illustrates the different types of typeof:
alert(typeof(Function)));
alert(typeof(new Function()));
alert(typeof(Array));
alert(typeof(Object));
alert(typeof(new Array()));
alert(typeof(new Date()));
alert(typeof(new Object())) ;
When you run this code, you can find that the first four statements will display "function", while the next three statements will display "object". It can be seen that a new function actually returns a function. This is very different from other objects. Other types such as Array and Object will return a normal object through the new operator. Although the function itself is also an object, it is still different from ordinary objects because it is also an object constructor. That is to say, you can create a new function to return an object, which has been introduced before. All objects whose typeof returns "function" are function objects. Such objects are also called constructors. Therefore, all constructors are objects, but not all objects are constructors.
Since the function itself is also an object, their type is function. Thinking of the class definitions of object-oriented languages such as C and Java, you can guess the role of the Function type, that is, you can define some methods and attributes for the function object itself. , with the help of the prototype object of the function, the definition of the Function type can be easily modified and expanded. For example, the function type Function is extended below and the method1 method is added to it. The function is to pop up a dialog box to display "function":
Function. prototype.method1=function(){
alert("function");
}
function func1(a,b,c){
return a b c;
}
func1. method1();
func1.method1.method1();
Pay attention to the last statement: func1.method1.mehotd1(), which calls the method1 method of the function object method1. Although it seems a bit confusing, a closer look at the syntax makes it clear: this is a recursive definition. Because method1 itself is also a function, it also has the properties and methods of the function object. All method extensions to the Function type have such recursive properties.
Function is the basis of all function objects, and Object is the basis of all objects (including function objects). In JavaScript, any object is an instance of Object. Therefore, the Object type can be modified so that all objects have some common properties and methods. Modifying the Object type is done through prototype:
Object.prototype. getType=function(){
return typeof(this);
}
var array1=new Array();
function func1(a,b){
return a b;
}
alert(array1.getType());
alert(func1.getType());
The above code adds the getType method to all objects, which returns the type of the object. The two alert statements will display "object" and "function" respectively.
Passing functions as parameters
The nature of function objects has been introduced before. Each function is represented as a special object, which can be easily assigned to a variable, and then the function call is made through this variable name. . As a variable, it can be passed to another function in the form of a parameter. This has been seen in the previous introduction to the JavaScript event handling mechanism. For example, the following program passes func1 as a parameter to func2:
function func1 (theFunc){
theFunc();
}
function func2(){
alert("ok");
}
func1(func2);
At the end In a statement, func2 is passed as an object to the formal parameter theFunc of func1, and then theFunc is called internally by func1. In fact, passing functions as parameters or assigning functions to other variables is the basis of all event mechanisms.
For example, if you need to perform some initialization work when the page is loading, you can first define an init initialization function, and then bind it to the page loading completion event through the window.onload=init; statement. The init here is a function object, which can be added to the window's onload event list.
Implicit parameters passed to the function: arguments
When a function call is made, in addition to the specified parameters, an implicit object - arguments is also created. arguments is an object that is similar to an array but not an array. It is similar because it has the same access properties as an array. It can be used to obtain values using syntax such as arguments[index] and has the array length attribute length. The arguments object stores the parameters actually passed to the function, and is not limited to the parameter list defined by the function declaration, for example:
function func(a,b){
alert(a);
alert( b);
for(var i=0;i
alert(arguments[i]);
}
}
func(1,2, 3);
When the code is run, it will display in sequence: 1, 2, 1, 2, 3. Therefore, when defining a function, even if the parameter list is not specified, the obtained parameters can still be referenced through arguments, which brings great flexibility to programming. Another attribute of the arguments object is callee, which represents a reference to the function object itself. This is helpful for implementing recursion of unnamed functions or ensuring the encapsulation of functions. For example, using recursion to calculate the sum of natural numbers from 1 to n:
var sum=function(n){
if(1==n)return 1;
else return n sum(n-1);
}
alert(sum(100));
The function contains a call to sum itself. However, for JavaScript, the function name is just a variable name. Calling sum inside the function is equivalent to calling a global variable, which cannot well reflect that it is calling itself, so A better approach would be to use the arguments.callee attribute:
var sum=function(n){
if(1==n)return 1;
else return n arguments.callee(n-1 ; prototype.p1=1;
alert(new Array().p1);
function func(){
alert(arguments.p1);
}
func();
When you run the code, you can find that the first alert statement is displayed as 1, which means that the array object has the property p1, and the func call is displayed as "undefined", that is, p1 is not a property of arguments. It can be seen that arguments is not an array object. .
The apply, call method and length attribute of the function
JavaScript defines two methods for the function object: apply and call. Their function is to bind the function to another object for execution. Both are only defined The method of parameters is different:
Function.prototype.apply(thisArg,argArray);
Function.prototype.call(thisArg[,arg1[,arg2…]]);
You can see from the function prototype By the way, the first parameter is named thisArg, that is, the this pointer inside all functions will be assigned the value thisArg, which achieves the purpose of running the function as a method of another object. Except for the thisArg parameter, both methods are parameters passed for the Function object.下面的代码说明了apply和call方法的工作方式:
//定义一个函数func1,具有属性p和方法A
function func1(){
this.p="func1-";
this.A=function(arg){
alert(this.p+arg);
}
}
//定义一个函数func2,具有属性p和方法B
function func2(){
this.p="func2-";
this.B=function(arg){
alert(this.p+arg);
}
}
var obj1=new func1();
var obj2=new func2();
obj1.A("byA"); //显示func1-byA
obj2.B("byB"); //显示func2-byB
obj1.A.apply(obj2,["byA"]); //显示func2-byA,其中[“byA”]是仅有一个元素的数组,下同
obj2.B.apply(obj1,["byB"]); //显示func1-byB
obj1.A.call(obj2,"byA"); //显示func2-byA
obj2.B.call(obj1,"byB"); //显示func1-byB
可以看出,obj1的方法A被绑定到obj2运行后,整个函数A的运行环境就转移到了obj2,即this指针指向了obj2。同样obj2的函数B也可以绑定到obj1对象去运行。代码的最后4行显示了apply和call函数参数形式的区别。
与arguments的length属性不同,函数对象还有一个属性length,它表示函数定义时所指定参数的个数,而非调用时实际传递的参数个数。例如下面的代码将显示2:
function sum(a,b){
return a+b;
}
alert(sum.length);
深入认识JavaScript中的this指针
this指针是面向对象程序设计中的一项重要概念,它表示当前运行的对象。在实现对象的方法时,可以使用this指针来获得该对象自身的引用。
和其他面向对象的语言不同,JavaScript中的this指针是一个动态的变量,一个方法内的this指针并不是始终指向定义该方法的对象的,在上一节讲函数的apply和call方法时已经有过这样的例子。为了方便理解,再来看下面的例子:
<script> <BR><!-- <BR>//创建两个空对象 <BR>var obj1=new Object(); <BR>var obj2=new Object(); <BR>//给两个对象都添加属性p,并分别等于1和2 <BR>obj1.p=1; <BR>obj2.p=2; <BR>//给obj1添加方法,用于显示p的值 <BR>obj1.getP=function(){ <BR> alert(this.p); //表面上this指针指向的是obj1 <BR>} <BR>//调用obj1的getP方法 <BR>obj1.getP(); <BR>//使obj2的getP方法等于obj1的getP方法 <BR>obj2.getP=obj1.getP; <BR>//调用obj2的getP方法 <BR>obj2.getP(); <BR>//--> <BR></script>
从代码的执行结果看,分别弹出对话框显示1和2。由此可见,getP函数仅定义了一次,在不同的场合运行,显示了不同的运行结果,这是有this指针的变化所决定的。在obj1的getP方法中,this就指向了obj1对象,而在obj2的getP方法中,this就指向了obj2对象,并通过this指针引用到了两个对象都具有的属性p。
由此可见,JavaScript中的this指针是一个动态变化的变量,它表明了当前运行该函数的对象。由this指针的性质,也可以更好的理解JavaScript中对象的本质:一个对象就是由一个或多个属性(方法)组成的集合。每个集合元素不是仅能属于一个集合,而是可以动态的属于多个集合。这样,一个方法(集合元素)由谁调用,this指针就指向谁。实际上,前面介绍的apply方法和call方法都是通过强制改变this指针的值来实现的,使this指针指向参数所指定的对象,从而达到将一个对象的方法作为另一个对象的方法运行。
每个对象集合的元素(即属性或方法)也是一个独立的部分,全局函数和作为一个对象方法定义的函数之间没有任何区别,因为可以把全局函数和变量看作为window对象的方法和属性。也可以使用new操作符来操作一个对象的方法来返回一个对象,这样一个对象的方法也就可以定义为类的形式,其中的this指针则会指向新创建的对象。在后面可以看到,这时对象名可以起到一个命名空间的作用,这是使用JavaScript进行面向对象程序设计的一个技巧。例如:
var namespace1=new Object();
namespace1.class1=function(){
//初始化对象的代码
}
var obj1=new namespace1.class1();
这里就可以把namespace1看成一个命名空间。
由于对象属性(方法)的动态变化特性,一个对象的两个属性(方法)之间的互相引用,必须要通过this指针,而其他语言中,this关键字是可以省略的。如上面的例子中:
obj1.getP=function(){
alert(this.p); //表面上this指针指向的是obj1
}
这里的this关键字是不可省略的,即不能写成alert(p)的形式。这将使得getP函数去引用上下文环境中的p变量,而不是obj1的属性。