从头开始学JavaScript (七)——函数

时间:2022-10-25 15:44:31

原文:从头开始学JavaScript (七)——函数

从头开始学JavaScript (七)——函数

一、return

函数在执行完return之后停止并立即退出。

return返回值;与return;

如下两个例子:

 function sum(num1, num2) {
num1= num1 + num2;
return num1;
} var result = sum(5, 10);
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); //
howManyArgs(); //
howManyArgs(12); //

利用这一点,可以让函数接受任意个参数并分别实现相应的功能:

     function doAdd() {
if(arguments.length == 1) {
alert(arguments[0] + 10);
} else if (arguments.length == 2) {
alert(arguments[0] + arguments[1]);
}
} doAdd(10); //
doAdd(30, 20); //

arguments还可以和命名过的参数一起用:

   function doAdd(num1, num2) {
if(arguments.length == 1) {
alert(num1 + 10);
} else if (arguments.length == 2) {
alert(arguments[0] + num2);
}
}
doAdd(10); //
doAdd(30, 20); //

arguments的值永远与对应命名参数的值保持同步:

 function doAdd(num1, num2) {
alert(arguments[0] + num2);
} doAdd(10, 20); //3
doAdd(30, 20); //
  function doAdd(num1, num2) {
arguments[1] = 10;
alert(arguments[0] + num2);
} doAdd(10, 20); //
doAdd(30, 20); //

每次执行doAdd这个函数,都会将第二个参数重写(上述例子中是将第二个参数重新赋值为10)。这是因为,arguments对象中的值会自动反映到对应的命名参数,所以修改

arguments[1],也就相当于修改了num2,不过他们俩的内存空间是独立的,值同步。
没有传递值的命名参数将会被赋予undefined,比如:
         function doAdd(num1, num2) {
alert(num2);//undefined
} doAdd(10);
arguments还有一个属性:callee,它的作用是返回正在被执行的function
例如:
         function argumentsTest (a,b) {
alert(arguments.callee);//返回函数本身
}
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返回的是什么呢?
看个例子:
 function calleeLengthDemo(arg1, arg2) {
alert("arguments.length:" +arguments.length);//
alert("arguments.callee.length:" +arguments.callee.length);// }
calleeLengthDemo(1,2,3);

由此可以看出arguments.callee.length返回的是函数定义的参数,即形参。

三、没有重载

ECMAscript函数不能实现重载,不能够定义同样的函数然后通过编译器去根据不同的参数执行不同的函数。

例如:
  function addSomeNumber(num1){
return num1 + 100;
} function addSomeNumber(num2) {
return num2 + 200;
} var result = addSomeNumber(100); //
alert(result);
 function addSomeNumber(num1){
num1+=100;
return num1 + 100;
} function addSomeNumber(num2) {
return num2 + 200;
} var result = addSomeNumber(100); //
alert(result);
只要函数名一致(上述例子中的addSomeNumber),ECMAscript就会认为是同一个东西,那么后定义的就会覆盖先定义的。
对于ECMAscript函数来说,我自己本没有参数,你给我什么参数我就接受什么样的参数。