在JavaScript高级程序设计书中看到
ECMAScript函数中不能想传统意义上那样实现重载。而在其他语句中(Java)中,可以为一个函数编写两个定义,只要两个定义的签名(接受的参
数的类型和数量)不同即可。如前所述,ECMAScript函数没有签名,因为其参数是由包含多个值的数组来表示的。而没有函数签名,真正的重载是不可做到
的。但是ECMAScript函数可以通过检查传入函数中的参数的类型和数量并做出不同的反应,可以去模拟方法的重载。
深入理解的例子:
function addsomeSomeNumber(num){
return num+=100;
}
function addsomeSomeNumber(num){
return num+=200;
}
addsomeSomeNumber(100)//300
显然,这个例子中声明了两个同名函数,而结果则是后面的函数覆盖了前面的函数。
因此,要模拟出重载的效果,只有两种方法:1.参数的类型;2.参数的数量
本人一开始学会的通过参数类型来实现重载的方法(这个虽然能实现,但是很好的写好)
function sum(type,a,b){ switch(type) { case 'sum': return a+b; break; case 'mul': return a*b; break; } }
用Switch 语句通过参数类型来模拟出重载效果。
关于Switch 语句还有个有个小技巧:case的连续执行
function sum(type,a,b){ var s=0; switch(type) { case 'sum': s += a+b; case 'mul': s += a*b; return s; break; } }
当执行函数sum('sum',1,2)时,他会执行出值,明明case 'sum'没有return,也会有值,因为函数没遇到break,它也运行了case ‘mul’的函数。
当然重载还有别的方式实现,下面就介绍argument,在JavaScript高级程序设计是这么写的
在ECMAScript中的参数在内部用一个数组(类数组)来表示。在函数体内可以通过arguments对象来访问这个参数数组,从而获取函数每一个参数。 arguments对象只是与数组类似(它并不是Array的实例),因为可以使用方括号语法访问ta它每一个元素(即第一个元素是arguments[0]以此类推), 使用length属性来确定他传递进来多少个参数。
故可以用 arguments.length 来实现重载
var HeavyLoad = function () { var length = arguments.length; //获取函数实参的个数 if (length === 0) { console.log('no-param'); return this; } else if(length === 1) { console.log('1'); return this; } else if(length ===2) { console.log('2'); return this; } else { console.log('3'); return this; } };
HeavyLoad('a','b','c') //3
也可以根据传参的类型来重载
var HeavyLoad= function () { if (typeof arguments[0] === 'number') { console.log('number'); } if (typeof arguments[0] === 'string') { console.log('string'); } }; HeavyLoad(1) //number
递归阶乘函数的实现
arguments.callee是一个指向正在执行的函数指针,因此用它来是实现对函数的递归调用。(注释下js是单线程的,所以指向正在执行的函数,就是指向自己)
function factorial(num){ if(num <= 1){ return 1; } else{ return num * arguments.callee(num-1); } }