Function類型 ECMAScript中最有意思的就是函數了,有意思的根源,在於函數實際上是對象。每個函數都是Function的實例,具有屬性和方法。而重要的一點是,函數名,不過是指向函數的指針,不會與某個函數綁定。 1.函數定義 (1)創建函數有函數聲明法和函數表達式法。(2)函數名僅僅是指向 ...
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