一、return
函數在執行完return之后停止並立即退出。
return返回值;與return;
如下兩個例子:
1 function sum(num1, num2) { 2 num1= num1 + num2; 3 return num1; 4 } 5 6 var result = sum(5, 10); 7 alert(result);//15
function sum(num1, num2) { num1= num1 + num2; return; } var result = sum(5, 10); alert(result);//undefined;
直接return而不帶任何參數的情況一般用於需要提前停止函數執行而又不需要返回值的情況。
如下:
function counter() { for (var count = 1; ; count++) { console.log(count + "A"); if (count === 5) { return; } console.log(count + "B"); } console.log(count + "C"); } counter();
二、參數
ECMAscript函數參數的特點;
- 不介意傳遞進來多少個參數
- 不介意傳遞進來的參數的數據類型
之所以有上述兩個特點,是因為ECMAscript參數在內部是用一個數組表示的。函數接收到的始終是這個數組,而不關心數組中包含哪些參數,或者是否有參數。
實際上,在函數體內可以通過arguments對象來訪問這個參數數組,從而獲取傳遞給函數的每一個參數。
例如:
function sayHi(name, message) { alert("Hello " + name + ", " + message); } sayHi("楊小漾", "how are you today?");
也可以寫成:
function sayHi() { alert("Hello " + arguments[0]+ ", " + arguments[1]); } sayHi("Nicholas", "how are you today?");
因此,在javascript里面,給參數命名只是提供便利,並不是必需的。
使用arguments.length可以獲知有多少個參數傳遞給了函數,例如:
function howManyArgs() { alert(arguments.length); } howManyArgs("string", 45); //2 howManyArgs(); //0 howManyArgs(12); //1
利用這一點,可以讓函數接受任意個參數並分別實現相應的功能:
1 function doAdd() { 2 if(arguments.length == 1) { 3 alert(arguments[0] + 10); 4 } else if (arguments.length == 2) { 5 alert(arguments[0] + arguments[1]); 6 } 7 } 8 9 doAdd(10); //20 10 doAdd(30, 20); //50
arguments還可以和命名過的參數一起用:
1 function doAdd(num1, num2) { 2 if(arguments.length == 1) { 3 alert(num1 + 10); 4 } else if (arguments.length == 2) { 5 alert(arguments[0] + num2); 6 } 7 } 8 doAdd(10); //20 9 doAdd(30, 20); //50
arguments的值永遠與對應命名參數的值保持同步:
1 function doAdd(num1, num2) { 2 alert(arguments[0] + num2); 3 } 4 5 doAdd(10, 20); //30 6 doAdd(30, 20); //50
1 function doAdd(num1, num2) { 2 arguments[1] = 10; 3 alert(arguments[0] + num2); 4 } 5 6 doAdd(10, 20); //20 7 doAdd(30, 20); //40
每次執行doAdd這個函數,都會將第二個參數重寫(上述例子中是將第二個參數重新賦值為10)。這是因為,arguments對象中的值會自動反映到對應的命名參數,所以修改
arguments[1],也就相當於修改了num2,不過他們倆的內存空間是獨立的,值同步。
沒有傳遞值的命名參數將會被賦予undefined,比如:
1 function doAdd(num1, num2) { 2 alert(num2);//undefined 3 } 4 5 doAdd(10);
arguments還有一個屬性:callee,它的作用是返回正在被執行的function
例如:
1 function argumentsTest (a,b) { 2 alert(arguments.callee);//返回函數本身 3 } 4 argumentsTest(1,2,3,4);
在使用函數遞歸調用時推薦使用arguments.callee代替函數名本身。
例如:
function count(a){ if(a==1){ return 1; } return a + arguments.callee(--a); } var mm = count(2); alert(mm);
arguments.length返回的是傳遞給函數的參數個數,也叫實參;而arguments.callee.length返回的是什么呢?
看個例子:
1 function calleeLengthDemo(arg1, arg2) { 2 alert("arguments.length:" +arguments.length);//3 3 alert("arguments.callee.length:" +arguments.callee.length);//2 4 5 } 6 calleeLengthDemo(1,2,3);
由此可以看出arguments.callee.length返回的是函數定義的參數,即形參。
三、沒有重載
ECMAscript函數不能實現重載,不能夠定義同樣的函數然后通過編譯器去根據不同的參數執行不同的函數。
例如:
1 function addSomeNumber(num1){ 2 return num1 + 100; 3 } 4 5 function addSomeNumber(num2) { 6 return num2 + 200; 7 } 8 9 var result = addSomeNumber(100); //300 10 alert(result);
1 function addSomeNumber(num1){ 2 num1+=100; 3 return num1 + 100; 4 } 5 6 function addSomeNumber(num2) { 7 return num2 + 200; 8 } 9 10 var result = addSomeNumber(100); //300 11 alert(result);
只要函數名一致(上述例子中的addSomeNumber),ECMAscript就會認為是同一個東西,那么后定義的就會覆蓋先定義的。
對於ECMAscript函數來說,我自己本沒有參數,你給我什么參數我就接受什么樣的參數。