函数类型
1.函数也是对象,并且函数名仅仅是指向函数的指针。
var sum=function(num1,num2){
return num1+num2;
}
console.info(sum(10,20));//30
var anothersum=sum;
console.info(anothersum(10,20));//30
sum=null;
console.info(anothersum(10,20));//30
2.函数没有重载
3.函数声明和函数表达式的区别
在js中函数声明会在代码解析器一开始将函数声明体提升到顶部执行,因此即便调用函数语句在函数声明之前,也不会报错。
alert(sum(10,20));//不会出错
function sum(num1,num2){
return num1+num2;
}
而函数表达式在定义函数的时候,必须要等到代码执行到表达以后,才能调用此函数。
alert(sum(10,20));//出错
var sum=function(num1,num2){
return num1+num2;
}
4.作为值的函数
在js中,可以像传递参数一样,将一个函数传递给另一个函数,也可以将一个函数当作另一个函数的结果返回。如下
function callSomeFunction(someFunction,someArguments){
return someFunction(someArguments);
}
var add10=function(num){
return num+10;
}
alert(callSomeFunction(add10,10));//20
function greenting(name){
return "Hello"+name;
}
alert(callSomeFunction(greenting,"tzw"));//"Hello tzw"
注意:因为函数变量是函数指针,因此在传递函数参数时,不需要写圆括号。
另外,一个函数也可以当作另一个函数的结果返回(典型的例子为创建一个比较函数)。例如如下:
function createComparisonFunction(propertyName){
return function(Oject1,Object2){
var Value1=Object1[propertyName];
var Value2=Object2[propertyName];
if(Value1<Value2){
return -1;//升序返回-1
}else if(Value1>Value2){
return 1;//降序返回1
}else{
return 0;
}
}
}
- 函数的内部属性
函数内部有两个对象:arguments和this。arguments对象是用来保存函数参数,并且这个对象有一个名叫callee的属性,该属性是一个指针,是来指向该拥有arguments对象的函数。利用阶乘函数来看:
function factorial(num){
if(num<=1){
return 1;
}else if(num>1){
return num*arguments.callee(num-1);
}
}
this是引用的是函数已执行的环境对象,当在网页的全局作用域中调用函数的话,则是指windows对象。
window.color="red";
var o={"color":"blue"};
function sayColor(){
console.info(this.color);//red
}
o.sayColor=sayColor;
o.sayColor();//blue
还有一个特殊的属性:caller。这个属性保存着调用当前函数的函数引用。
function outer(){
inner();
}
function inner(){
console.info(inner.caller);
}
outer();
如果需要更加离散的耦合,则可以把inner替换成arguments.callee即可;
function outer(){
inner();
}
function inner(){
console.info(arguments.callee.caller);
}
outer();
- 函数的属性和方法
函数也是对象,所以函数也会包含属性和方法。每个函数包含两个属性:length和prototype。length:指定义的函数所能接受的参数的个数。每个函数也还有两个非继承而来的方法:apply()和call(),用来设置函数体内this对象的值。
apply()接受两个参数,第一个为运行的函数的作用域,第二个参数为参数数组。
function sum(num1,num2){
return num1+num2;
}
function callsum1(num1,num2){
return sum.apply(this,arguments);//传入arguments对象
}
function callsum2(num1,num2){
return sum.apply(this,[num1,num2]);//传入参数数组
}
alert(callsum1(10,10));//20
alert(callsum2(10,10));//20
call方法同样也是有两个参数,第一个参数为this,运行函数的作用域,第二个参数就需要将所有参数逐一列出来。
function callsum3(num1,num2){
return sum.call(this,num1,num2);//传入参数
}
alert(callsum3(10,10));//20
实际上apply和call真正常用来扩充函数运行的作用域。
window.color="red";
var 0={"color":"blue"};
function sayColor(){
alert(this.color);
}
sayColor();//red
sayColor.call(this);//red
sayColor.call(window);//red
sayColor.call(o);//blue
用call和apply最大的好处在于对象与方法不需要有耦合关系,之前还需要将方法放入对象中,再调用。现在只需要用call和apply就可以了。
另外,还提供了一个bind()方法,这个方法会创建一个函数(方法)的实例,他的this值会绑定到bind传入的参数。
window.color="red";
var 0={"color":"blue"};
function sayColor(){
alert(this.color);
}
var objectSayColor=sayColor.bind(o);//this值绑定了o对象
objectSayColor();//blue