创建可重载的方法
obj是被创建重载对象的方法
name是重载的函数名
fn是接受不同参数个数的函数体
实际上obj[name]并不是指定的fn,而是如下的匿名函数,每一次为obj[name]
指定参数时,就相当于在匿名函数的后面加上了(arguments)使其立即执行。
此时就可以通过匿名函数内部的判断条件来判断是否有符合在重载函数内的
arguments(通过闭包)来执行函数
通过逐步的addMethod形成了类似于链式调用的感觉,
比如,第一次调用addMethod,addMethod中的obj[name]是一个保存有undefined的old和传入的第一个函数体引用的匿名函数,而第二次调用addMethod,首先会发现存在obj[name] (第一次定义的匿名函数)(并且内部还包含两个引用),于是将这个赋给old,于是新old[name]就又成为了一个新的包含old和fn引用的匿名函数,而这个old还包含了一个old和一个fn的引用一直延续下去
于是在调用obj[name] (后接着一些参数)时,就会先去找最新的那个obj[name],进行判断,若不对,则通过old进入上一级链式调用,去寻找上一层的obj[name]直到找的符合判断条件的为止
function addMethod(obj,name,fn) {
//obj可能原本存在同名函数
var old = obj[name];
//注意这个函数并没有被执行
obj[name] = function () {
//在匿名函数内保存着对导入的函数体fn的引用,在之后的调用中
//才可以取到相应fn的值
if(fn.length===arguments.length) {
//实际上是使用当前的对象传入的参数来送入fn来执行
return fn.apply(this, arguments);
}
//同理存在着对old的引用,old并未消亡
else if(typeof old === "function") {
return old.apply(this,arguments);
}
};
}