Function类型
ECMAScript中最有意思的就是函数了,有意思的根源,在于函数实际上是对象。每个函数都是Function的实例,具有属性和方法。而重要的一点是,函数名,不过是指向函数的指针,不会与某个函数绑定。
1.函数定义
(1)创建函数有函数声明法和函数表达式法。(2)函数名仅仅是指向函数的指针,所以一个函数可能会有多个名字。(3)函数没有重载,后面会覆盖前面。(4)函数声明会最先被解析,而函数表达式则不会。
1 alert(sum(10,10)); 2 function sum(num1,num2){ 3 return num1+num2; 4 }; //函数声明定义函数,会被率先解析,即使在函数声明之前调用函数,也不会报错 5 6 var sum=function(num1,num2){ 7 return num1+num2; 8 }; //函数表达式定义函数,不会被率先解析,如果在之前调用函数,会报错 9 10 11 12 function sum(num1,num2){ //函数名仅仅是指向函数的指针,换句话说,一个函数可以有多个名字 13 return num1+num2; 14 }; 15 alert(sum(10,10)); //20 16 var anotherSum=sum; //注意,使用不带括号的函数名是访问函数指针,而非调用函数,写成sum()就变成调用函数了 17 alert(anotherSum(10,10)); //20 18 sum=null; 19 alert(anotherSum(10,10)); //20,即使将sum设置为null,任然可以正常调用anotherSum() 20 21 22 23 function addSomeNumber(num){ 24 return num+100; 25 }; 26 function addSomeNumber(num){ 27 return num+200; 28 }; 29 var result=addSomeNumber(100); //300,将函数名想象成指针,就能理解为什么没有重载,后面的会覆盖前面的 30 alert(result);
2.函数作为值
ECMAScript中的函数名本身就是变量,所以,函数也可以作为值来始用。不仅可以将函数当作参数来传递,而且可以当做另一个函数的结果返回。从一个函数中返回另一个函数,而是极其有用的方法。
1 /*作为值的函数*/ 2 function callSomeFunction(someFunction,someArgument){ 3 return someFunction(someArgument); 4 }; //第一个参数应该是一个函数,第二个参数应该是要传递给该函数的一个值 5 6 function add10(num){ 7 return num+10; 8 }; 9 var result=callSomeFunction(add10,10); 10 alert(result); //20 11 function getGreeting(name){ 12 return "Hello,"+name; 13 }; 14 var result2=callSomeFunction(getGreeting,"Blue Beginner"); 15 alert(result2); //"Hello,Blue Beginner",需要注意的是,访问函数的指针而不是调用函数的话,一定不要带括号 16 17 18 /*从一个函数中返回另一个函数,这是极为有用的方法*/ 19 function creatComparisonFunction(propertyName){ 20 return function(object1,object2){ 21 var value1=object1[propertyName]; 22 var value2=object2[propertyName]; 23 return value2-value1; //此处为一个比较函数 24 }; 25 }; 26 var data=[{name:"Zachary",age:28},{name:"Nicholas",age:29}]; 27 data.sort(creatComparisonFunction("name")); 28 alert(data[0].name); //Zachary 29 data.sort(creatComparisonFunction("age")); 30 alert(data[0].name); //Nicholas
3.函数的属性和方法
(1)函数内部有两个特殊的对象:arguments和this。arguments用来保存函数的参数,它有一个callee的属性,指向拥有这个arguments的函数。this引用的是函数执行的环境对象。
(2)每个函数都包含两个属性:length和prototype。length:参数的个数。prototype:最耐人寻味,对于ECMAScript中的引用类型而言,它是保存所有实例方法的真正所在。
(3)每个函数都包含两个非继承而来的方法:apply(),call(),用途是在特定的作用域中调用函数。强大在,扩充函数的作用域。
(4)ECMAScript5还定义的一个bind()方法。该方法会创建一个函数的实例。
1 /*函数的内部属性*/ 2 function factorial(num){ //这是一个经典的阶乘函数 3 if(num<=1){ 4 return 1; 5 }else{ 6 return num*arguments.callee(num-1); //这里,不用factorial(num-1) 7 } 8 }; 9 var trueFactorial=factorial; 10 factorial=function(){ 11 return 0; 12 }; 13 alert(trueFactorial(5)); //120 14 alert(factorial(5)); //0 15 //将factorial值赋给trueFactorial后,后者便拥有了arguments,这样,中途改变factorial,阶乘函数照样有用,而此时的factorial只是一个返回0的函数罢了 16 17 function outer(){ 18 inner(); 19 }; 20 function inner(){ 21 alert(inner.caller); 22 }; 23 outer(); 24 /*caller*/ 25 26 27 28 /*函数的属性和方法*/ 29 window.color="red"; 30 var o={color:"blue"}; 31 function sayColor(){ 32 alert(this.color); 33 }; 34 sayColor(); //red 35 sayColor.apply(this); //red 36 sayColor.apply(window); //red 37 sayColor.apply(o); //blue 38 39 40 window.color="red"; 41 var o={color:"blue"}; 42 function sayColor(){ 43 alert(this.color); 44 }; 45 var objectSayColor=sayColor.bind(o); 46 objectSayColor(); //blue