Javascript学习---1、函数
2010-12-09 22:43 名刘天下 阅读(271) 评论(0) 编辑 收藏 举报在很多语言中,函数(Java里面成为方法)和对象时截然不同的两种东西。函数被定义为对象的动作。但是在JavaScript中,函数实际上也是对象,与其他的引用类型一样,可以具有属性和方法。
1、函数的声明
函数的声明比较简单,可以通过2种方式进行声明:函数声明式和函数表达式(其实还有第三种Function构造函数方式,但是我们基本不用,所以不提也罢)
1.1 函数声明式。最常用的方式了,如下所示的例子:
1: function sum(num1,num2)
2: {
3: return num1 + num2;
4: }
注意:函数名实际上也是一个指向函数对象的指针,而不会与某个函数绑定。
1.2 函数表达式。和函数声明式基本相同。如下所示:
1: var sum = function(num1,num2) {
2: return num1 + num2;
3: ;
上述代码定义了变量sum,并将其初始化为1个函数。当然,此处函数的定义采用了匿名函数的方式。另外注意语句的最后还有个分号,就像声明其他变量时一样;
由于函数名仅仅是指向函数的指针,因此函数名与包含对象指针的其他变量没有什么不同。如下代码所示:
1: function sum(num1,num2)
2: {
3: return num1+num2;
4: }
5: alert(sum(10,10)); //20
6: var anotherSum=sum; //anotherSum和sum指向了同一个函数
7: alert(another(10,10)); //20
8: sum =null; //sum设为null,并不会影响anotherSum
9: alert(another(10,10)); //20
注意:在第6行中,使用不带括号的函数名是访问函数指针,而带括号则是调用函数!
1.3 函数声明与函数表达式的区别
1: alert(sum(10,10));
2: function sum(num1,num2){
3: return num1+num2;
4: }
1: alert(sum(10,10));
2: var sum=function(num1,num2)
3: {
4: return num1+num2;
5: };
1: function add(num){
2: return num+100;
3: }
4: function add(num){
5: return num+200;
6: }
7: var result=add(100);
8: alert(result);
1: function factorial(num){
2: if(num<=1)
3: return 1;
4: else
5: return num*factorial(num-1);
6: }
该阶乘函数执行起来是没有问题的,但是它也存在一个问题:函数的执行和函数名factorial(第5行所用)紧紧耦合在一起。此时,可以使用arguments.callee属性进行改善,如下所示:
1: function factorial(num)
2: {
3: if(num<=1)
4: return 1;
5: else
6: return num*arguments.callee(num-1);
7: }
改善的代码提高了代码的可复用性了。
2、this:this是Javascript中非常有用的一个特殊对象,其作用大致和java、c#中的this类似。this引用的是函数据以执行操作的对象-或者可以说,this是函数在执行时所处的作用域。(当在网页的全局作用域中调用时,this对象引用的window)
1: window.color="red";
2: var o ={color:"blue";}
3: function sayColor(){
4: alert(this.color);
5: }
6: sayColor(); //“red”,在全局作用域中调用,this指向window
7: o.sayColor=sayColor;
8: o.sayColor(); //“blue” 此时this指的当然就是o了
注意:
函数的名字仅仅是一个包含指针的变量而已。因此,即使是在不同的执行环境中,全局的sayColor函数与o.sayColor指向的仍然是同一个函数!
1: function sayName(name){
2: alert(name)
3: }
4: function sum(n1,n2){
5: return n1+n2;
6: }
7: alert(sayName.length);//output :1
8: alert(sum.length); //output:2
call([thisObj[,arg1[, arg2[, [,.argN]]]]])
参数
thisObj:可选项。将被用作当前对象的对象。
arg1, arg2, , argN:可选项。将被传递方法参数序列。apply方法
apply([thisObj[,argArray]])
参数
thisObj:可选项。将被用作当前对象的对象。
argArray:可选项。将被传递给该函数的参数数组。
1: function sum(n1,n2){
2: return n1+ n2;
3: }
4: function callsum(n1,n2){
5: return sum.call(this,n1,n2);
6: }
7: alert(callsum(10,20)); //output 30
1: var number =10;
2: function sum(n1,n2){
3: return this.number + n1+ n2;
4:
5: function callsum(n1,n2){
6: this.number =20;
7: return sum.call(this,n1,n2);
8:
9: alert(sum(10,20)); //output 40
10: alert(callsum(10,20)); //output 50
上述代码中,为什么sum(10,20)会输出40呢?由于sum函数处于全局作用域中,因为在执行sum时,this指向的对象即为window,而var number=10,其实等价于var window.number=10,因此输出40。而在调用callsum时,在callsum函数内部先定义了一个它的属性this.number=20,而后,在执行sum.call语句时,那个this所指的自然是目前所在的函数callsum,因此在执行sum函数时,sum函数内的this所指的就是callsum,而callsum.number=20,因此最终结果为50了。
不好意思,,《javascript高级程序设计II》中也列举了相应的示例用来说明call和apply的主要用途的例子。代码如下:
1: window.color="red" ;
2: var o={color:"blue"};
3: function sayColor(){
4: alert(this.color);
5: }
6: sayColor(); //outpu: red
7: sayColor.call(this);//output:red
8: sayColor.call(window);//output:red
9: sayColor.call(o);//output:blue
这个虽然比较简单,但是对于call的用法其实展示的比较清楚了。
第6行直接调用sayColor()时,因为此时是在全局作用域中进行调用的,因此函数体内的this指向的就是window这个全局对象,所以输出的其实是window.color;
第7,8行其实是等同的。因为在全局作用域中的this就是window;
第9行则是最具代表性的。在执行sayColor.call(o)时,sayColor函数体内的this对象指向了o,因此输出blue.
主要参考:《javascript高级程序设计第二版》