Function类型
定义函数的三种方法:
一 函数声明语法定义函数
1 function sum1(num1,num2){ 2 return num1+num2; 3 } 4 alert(sum1());//NaN(本来要返回值得操作数,却没有返回值得操作,这样就不会抛出错误,继续执行下面的代码),因为调用sum1()没有传值,所以没有返回值 5 alert(sum1(100,200));//300 6 alert(typeof sum1);//function 7 alert(sum1);//function sum1(num1,num2){return num1+num2;}
二 函数表达式定义函数
1 var sum2 = function(num1,num2){ 2 return num1+num2; 3 }; 4 alert(sum2(100,200)); 5 alert(typeof sum2);//function 6 alert(sum2);//function(num1,num2){return num1+num2;}
三 Function构造函数定义函数
1 var sum3 = new Function("num1,num2","return num1+num2"); 2 alert(sum3(100,200));//300 3 alert(typeof sum3);//function 4 alert(sum3);//function anonymous(num1,num2,/**/){return num1+num2}
函数声明定义函数和函数表达式定义函数的区别:
1 alert(sum4(100,200));//300 2 function sum4(num1,num2){ 3 return num1+num2; 4 }
1 alert(sum5(100,300));//Property 'sum5' of object [object Object] is not a function 2 var sum5 = function(num1,num2){ 3 return num1+num2; 4 };
如何理解函数没有重载!
传统意义上,只要这两个定义的签名(接受的参数的类型和数量)不同即可。
理解一:从从函数名是指针理解。
1 function sum(num1,num2){ 2 return num1+num2; 3 } 4 function sum(num1,num2){ 5 return num1-num2; 6 } 7 alert(sum(100,200));//-100
可以理解:第一次定义的sum指针指向位置一
第二次定义的sum指针指向位置二,sum被重新赋值了。
理解二:函数的命名参数不是必须的。而且可以通过arguments对象访问函数体内的参数数组。
1 function add(num1,num2){ 2 return arguments[0]+arguments[1]; 3 } 4 alert(add(100,100));//200
ps:由于命名函数不是必须的,在传统意义上的函数重载在js中根本不起作用。
但是可以利用arguments实现函数重载!
1 function doAdd(){ 2 if(arguments.length == 1){ 3 return arguments[0] + 10; 4 }else if(arguments.length ==2){ 5 return arguments[0] + arguments[1]; 6 } 7 } 8 alert(doAdd(10));//20 9 alert(doAdd(10,90));//100
函数内部对象:arguments和this,函数内容属性:arguments.callee和caller
arguments对象用于访问函数的参数,但它有callee属性,用于消除函数的耦合。
arguments.callee是一个指针,指向该arguments所在的函数。
1 function fun1(num){ 2 if(num<=1){ 3 return 1; 4 }else{ 5 return num*arguments.callee(num-1); 6 } 7 } 8 alert(fun1(5));//120 9 10 var fun2 = fun1; 11 fun1 = function(num){ 12 return 0; 13 } 14 alert(fun2(5));//120 15 alert(fun1(5));//0
ps:即使fun1函数被重写了,fun2也能正常的递归。因为fun2指针指向原来的函数,而且arguments.callee解除了fun1的耦合。
this的值是函数据以执行的环境对象。通过例子理解:
1 var color = "red"; 2 var o ={color:"blue"}; 3 function putcolor(){ 4 return this.color; 5 } 6 alert(putcolor());//red 7 8 o.putcolor = putcolor; 9 alert(o.putcolor());//blue
ps:在全局环境调用putcolor(),当前的执行环境是全局环境,this是window对象。
o对象定义了putcolor方法,实质o.putcolor和putcolor指向同一个函数。o.putcolor()的执行环境是o,this是o对象。
caller:保存着调用当前函数的函数的引用, 如果是在全局作用域中调用当前函数,它的值为null。
function inner(){ alert(inner.caller); } function outer(){ inner(); } inner();//null outer();//function outer(){inner();}
函数外部的属性:length和prototype,外部的方法:apply()和call()和bind()
length:代表函数里面有多少个命名参数。
1 function fun1(num1){ 2 return num1; 3 } 4 function fun2(num1,num2){ 5 return num1+num2; 6 } 7 function fun3(){ 8 return 0; 9 } 10 alert(fun1.length);//1 11 alert(fun2.length);//2 12 alert(fun3.length);//0
prototype:原型模式扩展构造函数的属性。
apply()和call()作用一样,在特定的作 用域中调用函数,实际上等于设置函数体内this对象的值。
它们真正强大的地方是能够扩充函数 赖以运行的作用域
apply()和call()
1 function sum(num1,num2){ 2 return num1+num2; 3 } 4 function callsum1(num1,num2){ 5 return sum.apply(this,arguments); 6 } 7 function callsum2(num1,num2){ 8 return sum.apply(this,[num1,num2]); 9 } 10 function callsum3(num1,num2){ 11 return sum(num1,num2); 12 } 13 function callsum4(num1,num2){ 14 return sum.call(this,num1,num2); 15 } 16 alert(callsum1(100,200));//300 17 alert(callsum2(100,200));//300 18 alert(callsum3(100,200));//300 19 alert(callsum4(100,200));//300
ps:这个例子不能很好的突出apply和call的特点。
但是可以很好区别apply和call第二个参数的不同:第一个参数是对象。
但是第二个参数有区别,前者是arguments或者数组;后者为独立参数,而且不止两个参数。
展现扩充函数赖以运行的作用域的例子:
1 function color(str){ 2 alert(str); 3 } 4 var o = new Object(); 5 o.color = function (str){ 6 alert(str+" changed"); 7 } 8 function colorChange(str){ 9 this.color(str); 10 } 11 colorChange.apply(this,["red"]);//red 12 colorChange.apply(o,["red"]);//red changed
ps:colorChange()函数内的this值,已经被apply()的第一个参数设置了。
因此第一个警告框输出的是window对象的color(),
第二个警告框输出的是o对象的color()
1 window.color = "red"; 2 var o ={color:"blue"}; 3 function sayColor(){ 4 alert(this.color); 5 } 6 sayColor();//red 7 sayColor.call(this);//red 8 sayColor.call(window);//red 9 sayColor.call(o);//blue
ps:call()的第一个参数设置了sayColor()的this值。
function.bind(object):会创建一个新函数实例,而且函数中this的值绑定到bind传入的参数,例子
1 window.color = "red"; 2 var o ={color:"blue"}; 3 function sayColor(){ 4 alert(this.color); 5 } 6 var anotersayColor = sayColor.bind(o); 7 anotersayColor();//blue
ps:可见bind()的用途